One place for hosting & domains

      Client

      How To Create an HTTP Client with Core HTTP in Node.js


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      It’s common for a modern web application to communicate with other servers to accomplish a task. For example, a web app that allows you to purchase a book online may involve communication between a customer orders server, a book inventory server, and a payment server. In this design, the different services communicate via web APIs—standard formats that allow you to programmatically send and receive data. In a Node.js app, you can communicate with web APIs by making HTTP requests.

      Node.js comes bundled with an http and an https module. These modules have functions to create an HTTP server so that a Node.js program can respond to HTTP requests. They can also make HTTP requests to other servers. This key functionality equips Node.js programmers to create modern, API-driven web applications with Node.js. As it’s a core module, you do not need to install any libraries to use it.

      In this tutorial, you will use the https module to make HTTP requests to JSON Placeholder, a fake REST API for testing purposes. You will begin by making a GET request, the standard HTTP request to receive data. You will then look at ways to customize your request, such as by adding headers. Finally, you will make POST, PUT, and DELETE requests so that you can modify data in an external server.

      Prerequisites

      • This tutorial requires that you have Node.js installed. Once installed, you will be able to access the https module that’s used throughout the tutorial. This tutorial uses Node.js version 10.19.0. To install Node.js on macOS or Ubuntu 18.04, follow the steps in How To Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.

      • The methods used to send HTTP requests have a Stream-based API. In Node.js, streams are instances of event emitters. The way in which you respond to data coming from a stream is the same as the way in which you respond to data from events. If you are curious, you can get more in-depth knowledge of event emitters by reading our Using Event Emitters in Node.js guide.

      Step 1 — Making a GET Request

      When you interact with an API, you typically make GET requests to retrieve data from web servers. In this step, you’ll look at two functions to make GET requests in Node.js. Your code will retrieve a JSON array of user profiles from a publicly accessible API.

      The https module has two functions to make GET requests—the get() function, which can only make GET requests, and the request() function, which makes other types of requests. You will begin by making a request with the get() function.

      Making Requests with get()

      HTTP requests using the get() function have this format:

      https.get(URL_String, Callback_Function) {
          Action
      }
      

      The first argument is a string with the endpoint you’re making the request to. The second argument is a callback function, which you use to handle the response.

      First, set up your coding environment. In your terminal, create a folder to store all your Node.js modules for this guide:

      Enter that folder:

      Create and open a new file in a text editor. This tutorial will use nano as it’s available in the terminal:

      • nano getRequestWithGet.js

      To make HTTP requests in Node.js, import the https module by adding the follow line:

      requests/getRequestWithGet.js

      const https = require('https');
      

      Note:: Node.js has an http and an https module. They have the same functions and behave in a similar manner, but https makes the requests through the Transport Layer Security (TLS/SSL). As the web servers you are using are available via HTTPS, you will use the https module. If you are making requests to and from URLs that only have HTTP, then you would use the http module.

      Now use the http object to make a GET request to the API to retrieve a list of users. You will use JSON Placeholder, a publicly available API for testing. This API does not keep a record of any changes you make in your requests. It simulates a real server, and returns mocked responses as long as you send a valid request.

      Write the following highlighted code in your text editor:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => { });
      

      As mentioned in the function signature, the get() function takes two parameters. The first is the API URL you are making the request to in string format and the second is a callback to handle the HTTP response. To read the data from your response, you have to add some code in the callback.

      HTTP responses come with a status code. A status code is a number that indicates how successful the response was. Status codes between 200 and 299 are positive responses, while codes between 400 and 599 are errors. You can learn more about status codes in our How To Troubleshoot Common HTTP Error Codes guide.

      For this request, a successful response would have a 200 status code. The first thing you’ll do in your callback will be to verify that the status code is what you expect. Add the following code to the callback function:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      });
      

      The response object that’s available in the callback has a statusCode property that stores the status code. If the status code is not 200, you log an error to the console and exit.

      Note the line that has res.resume(). You included that line to improve performance. When making HTTP requests, Node.js will consume all the data that’s sent with the request. The res.resume() method tells Node.js to ignore the stream’s data. In turn, Node.js would typically discard the data more quickly than if it left it for garbage collection—a periodic process that frees an application’s memory.

      Now that you’ve captured error responses, add code to read the data. Node.js responses stream their data in chunks. The strategy for retrieving data will be to listen for when data comes from the response, collate all the chunks, and then parse the JSON so your application can use it.

      Modify the request callback to include this code:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      });
      

      You begin by creating a new variable data that’s an empty string. You can store data as an array of numbers representing byte data or a string. This tutorial uses the latter as it’s easier to convert a JSON string to a JavaScript object.

      After creating the data variable, you create an event listener. Node.js streams the data of an HTTP response in chunks. Therefore, when the response object emits a data event, you will take the data it received and add it to your data variable.

      When all the data from the server is received, Node.js emits a close event. At this point, you parse the JSON string stored in data and log the result to the console.

      Your Node.js module can now communicate with the JSON API and log the list of users, which will be a JSON array of three users. However, there’s one small improvement you can make first.

      This script will throw an error if you are unable to make a request. You may not be able to make a request if you lose your internet connection, for example. Add the following code to capture errors when you’re unable to send an HTTP request:

      requests/getRequestWithGet.js

      ...
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      
      });
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      When a request is made but cannot be sent, the request object emits an error event. If an error event is emitted but not listened to, the Node.js program crashes. Therefore, to capture errors you add an event listener with the on() function and listen for error events. When you get an error, you log its message.

      That’s all the code for this file. Save and exit nano by pressing CTRL+X.

      Now execute this program with node:

      • node getRequestWithGet.js

      Your console will display this response:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      This means you’ve successfully made a GET request with the core Node.js library.

      The get() method you used is a convenient method Node.js provides because GET requests are a very common type of request. Node.js provides a request() method to make a request of any type. Next, this tutorial will examine how to make a GET request with request().

      Making Requests with request()

      The request() method supports multiple function signatures. You’ll use this one for the subsequent example:

      https.request(URL_String, Options_Object, Callback_Function) {
          Action
      }
      

      The first argument is a string with the API endpoint. The second argument is a JavaScript object containing all the options for the request. The last argument is a callback function to handle the response.

      Create a new file for a new module called getRequestWithRequest.js:

      • nano getRequestWithRequest.js

      The code you will write is similar to the getRequestWithGet.js module you wrote earlier. First, import the https module:

      requests/getRequestWithRequest.js

      const https = require('https');
      

      Next, create a new JavaScript object that contains a method key:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        method: 'GET'
      };
      

      The method key in this object will tell the request() function what HTTP method the request is using.

      Next, make the request in your code. The following codeblock highlights code that was different from the request made with the get() method. In your editor, enter all of the following lines:

      requests/getRequestWithRequest.js

      ...
      
      let request = https.request('https://jsonplaceholder.typicode.com/users?_limit=2', options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      });
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      To make a request using request(), you provide the URL in the first argument, an object with the HTTP options in the second argument, and a callback to handle the response in the third argument.

      The options variable you created earlier is the second argument, telling Node.js that this is a GET request. The callback is unchanged from when you first wrote it.

      You also call the end() method of the request variable. This is an important method that must be called when using the request() function. It completes the request, allowing it to be sent. If you don’t call it, the program will never complete, as Node.js will think you still have data to add to the request.

      Save and exit nano with CTRL+X, or the equivalent with your text editor.

      Run this program in your terminal:

      • node getRequestWithRequest.js

      You will receive this output, which is the same as the first module:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      You have now used the request() method to make a GET request. It’s important to know this function as it allows you to customize your request in ways the get() method cannot, like making requests with other HTTP methods.

      Next, you will configure and customize your requests with the request() function.

      Step 2 — Configuring HTTP request() Options

      The request() function allows you to send HTTP requests without specifying the URL in the first argument. In this case, the URL would be contained with the options object, and the request() would have this function signature:

      https.request(Options_Object, Callback_Function) {
          Action
      }
      

      In this step, you will use this functionality to configure your request() with the options object.

      Node.js allows you to enter the URL in the options object you pass to the request. To try this out, reopen the getRequestWithRequest.js file:

      • nano getRequestWithRequest.js

      Remove the URL from the request() call so that the only arguments are the options variable and the callback function:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        method: 'GET',
      };
      
      let request = https.request(options, (res) => {
      ...
      

      Now add the following properties to the options object:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users?_limit=2',
        method: 'GET'
      };
      
      let request = https.request(options, (res) => {
      ...
      

      Instead of one string URL, you have two properties—host and path. The host is the domain name or IP address of the server you’re accessing. The path is everything that comes after the domain name, including query parameters (values after the question mark).

      The options object can hold other useful data that goes into a request. For example, you can provide request headers in the options. Headers typically send metadata about the request.

      When developers create APIs, they may choose to support different data formats. One API endpoint may be able to return data in JSON, CSV, or XML. In those APIs, the server may look at the Accept header to determine the correct response type.

      The Accept header specifies the type of data the user can handle. While the API being used in these examples only return JSON, you can add the Accept header to your request to explicitly state that you want JSON.

      Add the following lines of code to append the Accept header:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users?_limit=2',
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        }
      };
      

      By adding headers, you’ve covered the four most popular options that are sent in Node.js HTTP requests: host, path, method, and headers. Node.js supports many more options; you can read more at the official Node.js docs for more information.

      Enter CTRL+X to save your file and exit nano.

      Next, run your code once more to make the request by only using options:

      • node getRequestWithRequest.js

      The results will be the same as your previous runs:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      As APIs can vary from provider to provider, being comfortable with the options object is key to adapting to their differing requirements, with the data types and headers being some of the most common variations.

      So far, you have only done GET requests to retrieve data. Next, you will make a POST request with Node.js so you can upload data to a server.

      Step 3 — Making a POST Request

      When you upload data to a server or want the server to create data for you, you typically send a POST request. In this section, you’ll create a POST request in Node.js. You will make a request to create a new user in the users API.

      Despite being a different method from GET, you will be able to reuse code from the previous requests when writing your POST request. However, you will have to make the following adjustments:

      • Change the method in the options object to POST
      • Add a header to state you are uploading JSON
      • Check the status code to confirm a user was created
      • Upload the new user’s data

      To make these changes, first create a new file called postRequest.js. Open this file in nano or an alternative text editor:

      Begin by importing the https module and creating an options object:

      requests/postRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users',
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json; charset=UTF-8'
        }
      };
      

      You change the path to match what’s required for POST requests. You also updated the method to POST. Lastly, you added a new header in your options Content-Type. This header tells the server what type of data you are uploading. In this case, you’ll be uploading JSON data with UTF-8 encoding.

      Next, make the request with the request() function. This is similar to how you made GET requests, but now you look for a different status code than 200. Add the following lines to the end of your code:

      requests/postRequest.js

      ...
      const request = https.request(options, (res) => {
        if (res.statusCode !== 201) {
          console.error(`Did not get a Created from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Added new user');
          console.log(JSON.parse(data));
        });
      });
      

      The highlighted line of code checks if the status code is 201. The 201 status code is used to indicate that the server created a resource.

      This POST request is meant to create a new user. For this API, you need to upload the user details. Create some user data and send that with your POST request:

      requests/postRequest.js

      ...
      
      const requestData = {
        name: 'New User',
        username: 'digitalocean',
        email: 'user@digitalocean.com',
        address: {
          street: 'North Pole',
          city: 'Murmansk',
          zipcode: '12345-6789',
        },
        phone: '555-1212',
        website: 'digitalocean.com',
        company: {
          name: 'DigitalOcean',
          catchPhrase: 'Welcome to the developer cloud',
          bs: 'cloud scale security'
        }
      };
      
      request.write(JSON.stringify(requestData));
      

      You first created the requestData variable, which is a JavaScript object containing user data. Your request does not include an id field, as servers typically generate these while saving the new data.

      You next use the request.write() function, which accepts a string or buffer object to send along with the request. As your requestData variable is an object, you used the JSON.stringify function to convert it to a string.

      To complete this module, end the request and check for errors:

      requests/postRequest.js

      ...
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      It’s important that you write data before you use the end() function. The end() function tells Node.js that there’s no more data to be added to the request and sends it.

      Save and exit nano by pressing CTRL+X.

      Run this program to confirm that a new user was created:

      The following output will be displayed:

      Output

      Added new user { name: 'New User', username: 'digitalocean', email: 'user@digitalocean.com', address: { street: 'North Pole', city: 'Murmansk', zipcode: '12345-6789' }, phone: '555-1212', website: 'digitalocean.com', company: { name: 'DigitalOcean', catchPhrase: 'Welcome to the developer cloud', bs: 'cloud scale security' }, id: 11 }

      The output confirms that the request was successful. The API returned the user data that was uploaded, along with the ID that was assigned to it.

      Now that you have learned how to make POST requests, you can upload data to servers in Node.js. Next you will try out PUT requests, a method used to update data in a server.

      Step 4 — Making a PUT Request

      Developers make a PUT request to upload data to a server. While this may be similar to POST requests, PUT requests have a different function. PUT requests are idempotent—you can run a PUT request multiple times and it will have the same result.

      In practice, the code you write is similar to that of a POST request. You set up your options, make your request, write the data you want to upload, and verify the response.

      To try this out, you’re going to create a PUT request that updates the first user’s username.

      As the code is similar to the POST request, you’ll use that module as a base for this one. Copy the postRequest.js into a new file, putRequest.js:

      • cp postRequest.js putRequest.js

      Now open putRequest.js in a text editor:

      Make these highlighted changes so that you send a PUT request to https://jsonplaceholder.typicode.com/users/1:

      requests/putRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users/1',
        method: 'PUT',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json; charset=UTF-8'
        }
      };
      
      const request = https.request(options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Updated data');
          console.log(JSON.parse(data));
        });
      });
      
      const requestData = {
        username: 'digitalocean'
      };
      
      request.write(JSON.stringify(requestData));
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      You first change the path and method properties of the options object. path in this case identifies the user that you are going to update. When you make the request, you check if the response code was 200, meaning that the request was OK. The data you are uploading now only contains the property you are updating.

      Save and exit nano with CTRL+X.

      Now execute this Node.js program in your terminal:

      You will receive this output:

      Output

      Updated data { username: 'digitalocean', id: 1 }

      You sent a PUT request to update a pre-existing user.

      So far you have learned how to retrieve, add, and update data. To give us a full command of managing data via APIs, you’ll next make a DELETE request to remove data from a server.

      Step 5 — Making a DELETE Request

      The DELETE request is used to remove data from a server. It can have a request body, but most APIs tend not to require them. This method is used to delete an entire object from the server. In this section, you are going to delete a user using the API.

      The code you will write is similar to that of a GET request, so use that module as a base for this one. Copy the getRequestWithRequest.js file into a new deleteRequest.js file:

      • cp getRequestWithRequest.js deleteRequest.js

      Open deleteRequest.js with nano:

      Now modify the code at the highlighted parts, so you can delete the first user in the API:

      requests/putRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users/1',
        method: 'DELETE',
        headers: {
          'Accept': 'application/json',
        }
      };
      
      const request = https.request(options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Deleted user');
          console.log(JSON.parse(data));
        });
      });
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      For this module, you begin by changing the path property of the options object to the resource you want to delete—the first user. You then change the method to DELETE.

      Save and exit this file by pressing CTRL+X.

      Run this module to confirm it works. Enter the following command in your terminal:

      The program will output this:

      Output

      Deleted user {}

      While the API does not return a response body, you still got a 200 response so the request was OK.

      You’ve now learned how to make DELETE requests with Node.js core modules.

      Conclusion

      In this tutorial, you made GET, POST, PUT, and DELETE requests in Node.js. No libraries were installed; these requests were made using the standard https module. While GET requests can be made with a get() function, all other HTTP methods are done via the request() method.

      The code you wrote was written for a publicly available, test API. However, the way you write requests will work for all types of APIs. If you would like to learn more about APIs, check out our API topic page. For more on developing in Node.js, return to the How To Code in Node.js series.



      Source link

      How To Harden OpenSSH Client on Ubuntu 18.04


      The author selected the Electronic Frontier Foundation Inc to receive a donation as part of the Write for DOnations program.

      Introduction

      Linux servers are often administered remotely using SSH by connecting to an OpenSSH server, which is the default SSH server software used within Ubuntu, Debian, CentOS, FreeBSD, and most other Linux/BSD-based systems. Significant effort is put into securing the server-side aspect of SSH, as SSH acts as the entry into your server.

      However, it is also important to consider security on the client-side, such as OpenSSH client.

      OpenSSH client is the “client” side of SSH, also known as the ssh command. You can learn more about the SSH client-server model in SSH Essentials: Working with SSH Servers, Clients, and Keys.

      When hardening SSH at the server side, the primary objective is to make it harder for malicious actors to access your server. However, hardening at the client side is very different, as instead you are working to defend and protect your SSH connection and client from various different threats, including:

      • Attackers on the network, known as “person-in-the-middle” attacks.
      • Compromised or malicious servers sending malformed data packets, nefarious control sequences, or large amounts of data to overload your client.
      • Human error, such as mistyping server addresses or configuration values.

      In this tutorial, you will harden your OpenSSH client in order to help ensure that outgoing SSH connections are as secure as possible.

      Prerequisites

      To complete this tutorial, you will need:

      • A device that you use as an SSH client, for example:

      • An SSH server that you want to connect to, for example:

        • A cloud server
        • A public service such as GitHub or GitLab
        • A third-party device that you are permitted to access

      Once you have these ready, log in to your SSH client device as a non-root user to begin.

      Step 1 — General Hardening

      In this first step, you will implement some initial hardening configurations in order to improve the overall security of your SSH client.

      The exact hardening configuration that is most suitable for your client depends heavily on your own threat model and risk threshold. However, the configuration described in this step is a general, all-round secure configuration that should suit the majority of users.

      Many of the hardening configurations for OpenSSH client are implemented using the global OpenSSH client configuration file, which is located at /etc/ssh/ssh_config. In addition to this, some configurations may also be set using the local SSH configuration file for your user, located at ~/.ssh/config.

      Before continuing with this tutorial, it is recommended to take a backup of both of these files, so that you can restore them in the unlikely event that something goes wrong.

      Take a backup of the files using the following commands:

      • sudo cp /etc/ssh/ssh_config /etc/ssh/ssh_config.bak
      • cp ~/.ssh/config ~/.ssh/config.bak

      This will save a backup copy of the files in their default location, but with the .bak extension added.

      Note that your local SSH configuration file (~/.ssh/config) may not exist if you haven’t used it in the past. If this is the case, it can be safely ignored for now.

      You can now open the global configuration file using your favorite text editor to begin implementing the initial hardening measures:

      • sudo nano /etc/ssh/ssh_config

      Note: The OpenSSH client configuration file includes many default options and configurations. Depending on your existing client setup, some of the recommended hardening options may already have been set.

      When editing your configuration file, some options may be commented out by default using a single hash character (#) at the start of the line. To edit these options, or have the commented option be recognized, you’ll need to uncomment them by removing the hash.

      Firstly, you should disable X11 display forwarding over SSH by setting the following options:

      /etc/ssh/ssh_config

      ForwardX11 no
      ForwardX11Trusted no
      

      X11 forwarding allows for the display of remote graphical applications over an SSH connection, however this is rarely used in practice. By disabling it, you can prevent potentially malicious or compromised servers from attempting to forward an X11 session to your client, which in some cases can allow for filesystem permissions to be bypassed, or for local keystrokes to be monitored.

      Next, you can consider disabling SSH tunneling. SSH tunneling is quite widely used, so you may need to keep it enabled. However, if it isn’t required for your particular setup, you can safely disable it as a further hardening measure:

      /etc/ssh/ssh_config

      Tunnel no
      

      You should also consider disabling SSH agent forwarding if it isn’t required, in order to prevent servers from requesting to use your local SSH agent to authenticate onward SSH connections:

      /etc/ssh/ssh_config

      ForwardAgent no
      

      In the majority of cases, your SSH client will be configured to use password authentication or public-key authentication when connecting to servers. However, OpenSSH client also supports other authentication methods, some of which are enabled by default. If these are not required, they can be disabled to further reduce the potential attack surface of your client:

      /etc/ssh/ssh_config

      GSSAPIAuthentication no
      HostbasedAuthentication no
      

      If you’d like to know more about some of the additional authentication methods available within SSH, you may wish to review these resources:

      OpenSSH client allows you to automatically pass custom environment variables when connecting to servers, for example, to set a language preference or configure terminal settings. However, if this isn’t required in your setup, you can prevent any variables being sent by ensuring that the SendEnv option is commented out or completely removed:

      /etc/ssh/ssh_config

      # SendEnv
      

      Finally, you should ensure that strict host key checking is enabled, to ensure that you are appropriately warned when the host key/fingerprint of a remote server changes, or when connecting to a new server for the first time:

      /etc/ssh/ssh_config

      StrictHostKeyChecking ask
      

      This will prevent you from connecting to a server when the known host key has changed, which could mean that the server has been rebuilt or upgraded, or could be indicative of an ongoing person-in-the-middle attack.

      When connecting to a new server for the first time, your SSH client will ask you whether you want to accept the host key and save it in your ~/.ssh/known_hosts file. It’s important that you verify the host key before accepting it, which usually involves asking the server administrator or browsing the documentation for the service (in the case of GitHub/GitLab and other similar services).

      Save and exit the file.

      Now that you’ve completed your initial configuration file hardening, you should validate the syntax of your new configuration by running SSH in test mode:

      You can substitute the . with any hostname to test/simulate any settings contained within Match or Host blocks.

      If your configuration file has a valid syntax, the options that will apply to that specific connection will be printed out. In the event of a syntax error, there will be an output describing the issue.

      You do not need to restart any system services for your new configuration to take effect, although existing SSH sessions will need to be re-established if you want them to inherit the new settings.

      In this step, you completed some general hardening of your OpenSSH client configuration file. Next, you’ll restrict the ciphers that are available for use in SSH connections.

      Step 2 — Restricting Available Ciphers

      Next, you will configure the cipher suites available within your SSH client to disable support for those that are deprecated/legacy.

      Begin by opening your global configuration file in your text editor:

      • sudo nano /etc/ssh/ssh_config

      Next, ensure that the existing Ciphers configuration line is commented out by prefixing it with a single hash (#).

      Then, add the following to the top of the file:

      /etc/ssh/ssh_config

      Ciphers -arcfour*,-*cbc
      

      This will disable the legacy Arcfour ciphers, as well as all ciphers using Cipher Block Chaining (CBC), which is no longer recommended for use.

      If there is a requirement to connect to systems that only support these legacy ciphers, you can explicitly re-enable the required ciphers for specific hosts by using a Match block. For example, to enable the 3des-cbc cipher for a specific legacy host, the following configuration could be used:

      /etc/ssh/ssh_config

      Match host legacy-server.your-domain
        Ciphers +3des-cbc
      

      Save and exit the file.

      Finally, as you did in Step 1, you may wish to test your SSH client configuration again to check for any potential errors:

      If you have added a Match block to enable legacy ciphers for a specific host, you can also specifically target that configuration during the test by specifying the associated host address:

      • ssh -G legacy-server.your-domain

      You’ve secured the ciphers available to your SSH client. Next, you will review the access permissions for files used by your SSH client.

      Step 3 — Securing Configuration File and Private Key Permissions

      In this step, you’ll lock down the permissions for your SSH client configuration files and private keys to help prevent accidental or malicious changes, or private key disclosure. This is especially useful when using a shared client device between multiple users.

      By default on a fresh installation of Ubuntu, the OpenSSH client configuration file(s) are configured so that each user can only edit their own local configuration file (~/.ssh/config), and sudo/administrative access is required to edit the system-wide configuration (/etc/ssh/ssh_config).

      However, in some cases, especially on systems that have been in existence for a long time, these configuration file permissions may have been accidentally modified or adjusted, so it’s best to reset them to make sure that the configuration is secure.

      You can begin by checking the current permissions value for the system-wide OpenSSH client configuration file using the stat command, which you can use to show the status or files and/or filesystem objects:

      • stat -c "%a %A %U:%G" /etc/ssh/ssh_config

      You use the -c argument to specify a custom output format.

      Note: On some operating systems, such as macOS, you will need to use the -f option to specify a custom format rather than -c.

      In this case, the %A %a %U:%G option will print the permissions for the file in octal and human-readable format, as well as the user/group that owns the file.

      This will output something similar to the following:

      Output

      644 -rw-r--r-- root:root

      In this case, the permissions are correct, root owns the file entirely, and only root has permission to write to/modify it.

      Note: If you’d like to refresh your knowledge on Linux permissions before continuing, you may wish to review An Introduction to Linux Permissions.

      However, if your own output is different, you should reset the permissions back to the default using the following commands:

      • sudo chown root:root /etc/ssh/ssh_config
      • sudo chmod 644 /etc/ssh/ssh_config

      If you repeat the stat command from earlier in this step, you will now receive the correct values for your system-wide configuration file.

      Next, you can carry out the same checks for your own local SSH client configuration file, if you have one:

      • stat -c "%a %A %U:%G" ~/.ssh/config

      This will output something similar to the following:

      Output

      644 -rw--r--r-- user:user

      If the permissions for your own client configuration file permissions are any different, you should reset them using the following commands, similarly to earlier in the step:

      • chown user:user ~/.ssh/config
      • chmod 644 ~/.ssh/config

      Next, you can check the permissions for each of the SSH private keys that you have within your ~/.ssh directory, as these files should only be accessible by yourself, and not any other users on the system.

      Begin by printing the current permission and ownership values for each private key:

      • stat -c "%a %A %U:%G" ~/.ssh/id_rsa

      This will output something similar to the following:

      Output

      600 -rw------- user:user

      It is extremely important that you properly lock down the permissions for your private key files, as failing to do so could allow other users of your device to steal them and access the associated servers or remote user accounts.

      If the permissions aren’t properly configured, use the following commands on each private key file to reset them to the secure defaults:

      • chown user:user ~/.ssh/id_rsa
      • chmod 600 ~/.ssh/id_rsa

      In this step, you assessed and locked down the file permissions for your SSH client configuration files and private keys. Next, you will implement an outbound allowlist to limit which servers your client is able to connect to.

      Step 4 — Restricting Outgoing Connections Using a Host Allowlist

      In this final step, you will implement an outgoing allowlist in order to restrict the hosts that your SSH client is able to connect to. This is especially useful for shared/multi-user systems, as well as SSH jump hosts or bastion hosts.

      This security control is specifically designed to help protect against human error/mistakes, such as mistyped server addresses or hostnames. It can be easily bypassed by the user by editing their local configuration file, and so isn’t designed to act as a defense against malicious users/actors.

      If you want to restrict outbound connections at the network level, the correct way to do this is using firewall rules. This is beyond the scope of this tutorial, but you can check out UFW Essentials: Common Firewall Rules and Commands.

      However, if you want to add some additional fail-safes, then this security control may be of benefit to you.

      It works by using a wildcard rule within your SSH client configuration file to null route all outbound connections, apart from those to specific addresses or hostnames. This means that if you were ever to accidentally mistype a server address, or attempt to connect to a server that you’re not supposed to, the request would be stopped immediately, giving you the opportunity to realize your mistake and take corrective action.

      You can apply this at either the system-level (/etc/ssh/ssh_config) or using your local user configuration file (~/.ssh/config). In this example, we will use the local user configuration file.

      Begin by opening the file, creating it if it doesn’t already exist:

      At the bottom of the file, add the following content, substituting in your own list of allowed IP addresses and hostnames:

      ~/.ssh/config

      Match host !203.0.113.1,!192.0.2.1,!server1.your-domain,!github.com,*
        Hostname localhost
      

      You must prefix IP addresses or hostnames with an exclamation point (!), and use commas to separate each item in the list. The final list item should be a single asterisk (*) without a prefixed exclamation point.

      If you’re running an SSH server on your machine too, you may wish to use a hostname value other than localhost, as this will cause the null routed connections to be sent to your own local SSH server, which could be counterproductive or confusing. Any nullrouted hostname is acceptable, such as null, do-not-use, or disallowed-server.

      Save and close the file once you’ve made your changes.

      You can now test that the configuration is working by attempting to connect to a disallowed destination using your SSH client. For example:

      • ssh disallowed.your-domain

      If the configuration is working properly, you will immediately receive an error similar to the following:

      Output

      Cannot connect to localhost: connection refused

      However, when you attempt to connect to an allowed destination, the connection will succeed as normal.

      In this final step, you implemented some additional fail-safes to help protect against human error and mistakes when using your SSH client.

      Conclusion

      In this article you reviewed your OpenSSH client configuration and implemented various hardening measures.

      This will have improved the security of your outgoing SSH connections, as well as helping to ensure that your local configuration files cannot be accidentally or maliciously modified by other users.

      You may wish to review the manual pages for OpenSSH client and its associated configuration file to identify any potential further tweaks that you want to make:

      Finally, if you want to harden OpenSSH at the server side too, check out How To Harden OpenSSH on Ubuntu 18.04.



      Source link

      Comment installer et configurer un démon et un client SNMP sur Ubuntu 18.04


      L’auteur a choisi Internet Archive pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Le rôle d’un administrateur système consiste en grande partie à recueillir des informations précises sur les serveurs et l’infrastructure. Il existe un certain nombre d’outils et d’options pour la collecte et le traitement de ce type d’informations. Beaucoup d’entre eux sont construits sur la base d’une technologie appelée SNMP.

      SNMP est l’abréviation de simple network management protocol (protocole simple de gestion de réseau). C’est un moyen pour les serveurs de partager des informations sur leur état actuel, et aussi un canal par lequel un administrateur peut modifier des valeurs prédéfinies. Si le protocole lui-même est léger, la structure des programmes qui implémentent SNMP peut rapidement gagner en complexité. Pour plus d’informations sur les bases du protocole SNMP, consultez notre article Introduction au SNMP.

      Dans ce guide, vous allez configurer les outils pour communiquer en utilisant le SNMP. Vous utiliserez deux serveurs Ubuntu 18.04 pour la démonstration. L’un contiendra le manager SNMP, qui parle à l’agent pour implémenter des dispositifs réseau. Il sera appelé manager server. L’autre serveur contiendra l’agent SNMP, qui agira sur les ordres du manager server. Il sera appelé agent server. Vous pouvez également choisir d’installer l’agent sur la machine manager, mais en les gardant séparés, il est plus facile de démontrer les fonctionnalités fournies par chaque composant.

      Conditions préalables

      Pour suivre ce tutoriel, vous aurez besoin de :

      Étape 1 – Installation du démon et des utilitaires SNMP

      Vous pouvez commencer à explorer comment le SNMP peut être implémenté sur un système en installant le démon et les outils sur vos serveurs Ubuntu.

      Depuis votre machine locale, connectez-vous au manager server en tant qu’utilisateur non root :

      • ssh your_username@manager_server_ip_address

      Mettez à jour l’index des paquets pour le gestionnaire de paquets APT :

      Ensuite, installez le logiciel SNMP :

      • sudo apt install snmp snmp-mibs-downloader

      Le paquet snmp fournit un ensemble d’outils en ligne de commande pour émettre des requêtes SNMP aux agents. Le paquet snmp-mibs-downloader aidera à installer et à gérer les fichiers MIB (Management Information Base), qui gardent la trace des objets du réseau.

      Ensuite, ouvrez un nouveau terminal sur votre machine locale et connectez-vous à l’agent server :

      • ssh your_username@agent_server_ip_address

      Sur l’agent server, mettez à jour l’index des paquets :

      Ensuite, installez le démon SNMP :

      Notez que vous n’avez pas besoin du paquet snmp-mibs-downloader, puisque l’agent server ne gérera pas de fichiers MIB.

      Maintenant que vous avez installé ces composants, vous allez configurer votre manager server.

      Étape 2 – Configuration du manager server SNMP

      Comme mentionné précédemment, la majeure partie du travail se fait dans l’agent server, de sorte que votre configuration sur le manager server sera plus simple. Il vous suffit de modifier un fichier pour vous assurer que les outils SNMP peuvent utiliser les données MIB supplémentaires que vous avez installées.

      Sur votre manager server, ouvrez le fichier /etc/snmp/snmp.conf dans votre éditeur de texte avec des privilèges sudo. Ce tutoriel utilisera nano :

      • sudo nano /etc/snmp/snmp.conf

      Dans ce fichier, il y a quelques commentaires et une seule ligne non commentée. Pour permettre au manager d’importer les fichiers MIB, commentez la ligne mibs : :

      /etc/snmp/snmp.conf

      # As the snmp packages come without MIB files due to license reasons, loading
      # of MIBs is disabled by default. If you added the MIBs you can reenable
      # loading them by commenting out the following line.
      #mibs :
      

      Enregistrez et fermez snmp.conf en appuyant sur CTRL+X, suivi de Y, puis ENTER (ENTRÉE) si vous utilisez nano.

      Vous avez maintenant terminé la configuration du manager server, mais vous devrez encore utiliser ce serveur pour vous aider à configurer votre agent server, ce que vous ferez à l’étape suivante.

      Étape 3 – Configuration de l’agent server SNMP

      En tant que véritable système client-serveur, l’agent server ne dispose d’aucun des outils externes nécessaires pour effectuer sa propre configuration SNMP. Vous pouvez modifier certains fichiers de configuration pour effectuer quelques changements, mais la plupart des changements que vous devez effectuer se feront en vous connectant à votre agent server à partir de votre manager server.

      Dans ce tutoriel, vous utiliserez la version 3 du protocole SNMP. Contrairement à SNMPv1 et v2, dans SNMPv3 chaque message contient des paramètres de sécurité qui sont codés. Dans cette étape, vous allez configurer les règles d’authentification et de contrôle d’accès SNMPv3.

      Pour commencer, sur votre agent server, ouvrez le fichier de configuration du démon avec des privilèges sudo :

      • sudo nano /etc/snmp/snmpd.conf

      À l’intérieur, vous devrez effectuer quelques modifications. Elles seront principalement utilisées pour bootstrapper votre configuration afin que vous puissiez la gérer à partir de votre autre serveur.

      Tout d’abord, vous devez modifier la directive agentAdress. Actuellement, elle est réglée pour n’autoriser que les connexions provenant de l’ordinateur local. Vous devrez commenter la ligne actuelle, et décommenter la ligne en dessous, qui autorise toutes les connexions.

      /etc/snmp/snmpd.conf

      #  Listen for connections from the local system only
      #agentAddress  udp:127.0.0.1:161
      #  Listen for connections on all interfaces (both IPv4 *and* IPv6)
      agentAddress udp:161,udp6:[::1]:161
      

      Remarque : étant donné qu’autoriser toutes les connexions n’est pas une bonne pratique en termes de sécurité, il est préférable de reverrouiller les connexions rapidement une fois le bootstrap terminé.

      Ensuite, vous insérerez temporairement une ligne createUser. Ces directives ne sont normalement pas conservées dans ce fichier ; vous allez les supprimer à nouveau dans un instant.

      L’utilisateur que vous créez sera appelé bootstrap et sera utilisé comme modèle pour créer votre premier utilisateur réel. Les paquets SNMP le font par un processus de clonage des propriétés de l’utilisateur.

      Lorsque vous définissez un nouvel utilisateur, vous devez spécifier le type d’authentification (MD5 ou SHA) et fournir une phrase de passe d’au moins huit caractères. Si vous prévoyez d’utiliser le cryptage pour le transfert, comme vous le ferez dans ce tutoriel, vous devez également préciser le protocole de confidentialité (DES ou AES) et, éventuellement, une phrase de passe de protocole de confidentialité. Si aucune phrase de passe de protocole de confidentialité n’est fournie, la phrase de passe d’authentification sera également utilisée pour le protocole de confidentialité.

      Ajoutez cette ligne createUser à la fin du fichier :

      /etc/snmp/snmpd.conf

      ...
      createUser bootstrap MD5 temp_password DES
      

      Maintenant que vous avez un nouvel utilisateur spécifié, vous pouvez configurer le niveau d’accès de cet utilisateur. Dans ce tutoriel, vous le configurerez pour votre utilisateur bootstrap, mais aussi pour le nouvel utilisateur que vous allez créer, appelé demo. Vous leur permettrez l’accès en lecture et en écriture en utilisant la directive rwuser (l’alternative est rouser pour l’accès en lecture seule).

      Vous imposerez également l’utilisation du cryptage en spécifiant priv après votre utilisateur. Si vous souhaitez restreindre l’utilisateur à une partie spécifique de la MIB, vous pouvez spécifier à la fin de la ligne l’identificateur de l’objet (OID) de plus haut niveau auquel l’utilisateur doit avoir accès.

      Pour les besoins de ce tutoriel, vos deux lignes seront les suivantes :

      /etc/snmp/snmpd.conf

      ...
      rwuser bootstrap priv
      rwuser demo priv
      

      Lorsque vous avez terminé d’effectuer ces modifications, enregistrez et fermez le fichier.

      Pour implémenter ces modifications, redémarrez le service snmpd sur votre agent server :

      • sudo systemctl restart snmpd

      Le démon SNMP écoutera les connexions sur le port :161. Configurez UFW pour autoriser les connexions depuis le manager server vers ce port :

      • sudo ufw allow from manager_server_ip_address to any port 161

      Pour savoir plus sur UFW, consultez le tutoriel Comment configurer un pare-feu avec UFW sur Ubuntu 18.04.

      Maintenant que l’agent server est configuré, vous pouvez vous connecter à votre agent server depuis le manager server pour vérifier la connexion.

      Étape 4 – Vérification de l’authentification par l’agent server

      Dans cette étape, vous allez effectuer un test pour vous assurer que vous pouvez vous connecter à l’agent server avec votre compte bootstrap. Avant cela, cependant, ce tutoriel abordera un peu la structure générale de l’envoi d’une commande SNMP.

      Lorsque vous utilisez la suite d’outils incluse dans le paquet snmp (la suite logicielle net-snmp), la façon dont vous devez appeler les commandes est régie par quelques règles. La première chose à faire est de s’authentifier auprès du démon SNMP avec lequel vous souhaitez communiquer. Cela implique généralement de fournir quelques informations. Les plus courantes sont les suivantes :

      • -v : cet indicateur est utilisé pour spécifier la version du protocole SNMP que vous souhaitez utiliser. Ce tutoriel utilisera v3.
      • -c : cet indicateur est utilisé si vous utilisez des chaînes communautaires de type SNMP v1 ou v2 pour l’authentification. Comme vous utilisez une authentification basée sur l’utilisateur de type v3, vous n’avez pas besoin de cet indicateur.
      • -u : ce paramètre est utilisé pour spécifier le nom d’utilisateur avec lequel vous souhaitez vous identifier. Pour lire ou modifier quoi que ce soit en utilisant le SNMP, vous devez vous authentifier avec un nom d’utilisateur connu.
      • -l : ceci est utilisé pour spécifier le niveau de sécurité avec lequel vous vous connectez. Les valeurs possibles sont noAuthNoPriv pour l’absence d’authentification et de cryptage, authNoPriv pour l’authentification mais pas de cryptage, et authPriv pour l’authentification et le cryptage. Le nom d’utilisateur que vous utilisez doit être configuré pour fonctionner au niveau de sécurité que vous spécifiez, sinon l’authentification ne réussira pas.
      • -a : ce paramètre est utilisé pour spécifier le protocole d’authentification qui est utilisé. Les valeurs possibles sont MD5 ou SHA. Cela doit correspondre aux informations qui ont été spécifiées lorsque l’utilisateur a été créé.
      • -x : ce paramètre permet de spécifier le protocole de cryptage qui est utilisé. Les valeurs possibles sont DES ou AES. Cela doit correspondre aux informations qui ont été spécifiées lorsque l’utilisateur a été créé. Ce paramètre est nécessaire chaque fois que priv est indiqué après la spécification de privilège de l’utilisateur, rendant le cryptage obligatoire.
      • -A : ceci est utilisé pour donner la phrase de passe d’authentification qui a été spécifiée lors de la création de l’utilisateur.
      • -X : il s’agit de la phrase de passe de cryptage qui a été spécifiée lors de la création de l’utilisateur. Si aucune n’a été spécifiée mais qu’un algorithme de cryptage a été donné, la phrase de passe d’authentification sera utilisée. Ceci est nécessaire lorsque le paramètre -x est donné ou lorsque la spécification de privilège d’un utilisateur est suivie d’un priv, nécessitant un cryptage.

      À l’aide de ces informations, vous pouvez construire vos commandes. Étant donné la configuration de votre utilisateur bootstrap, les commandes que vous utiliserez avec ce compte ressembleront à ça :

      snmp_command -u bootstrap -l authPriv -a MD5 -x DES -A temp_password -X temp_password remote_host snmp_sub_command_or_options
      

      À partir de votre manager server, effectuez un test pour vous assurer que votre compte bootstrap est disponible. Tapez ce qui suit pour afficher les informations système relatives à l’agent server :

      • snmpget -u bootstrap -l authPriv -a MD5 -x DES -A temp_password -X temp_password agent_server_ip_address 1.3.6.1.2.1.1.1.0

      La chaîne 1.3.6.1.2.1.1.1.0 est l’OID qui est responsable de l’affichage des informations du système. Elle renverra la sortie de uname -a sur le système à distance.

      Cela donnera le résultat suivant :

      Output

      SNMPv2-MIB::sysDescr.0 = STRING: Linux agent 4.15.0-66-generic #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64

      Maintenant que vous avez vérifié que vous pouvez vous authentifier auprès du serveur qui exécute le démon SNMP, vous pouvez créer votre compte utilisateur ordinaire.

      Étape 5 – Configuration du compte utilisateur ordinaire

      Bien que vous ayez spécifié les privilèges du compte utilisateur demo dans le fichier snmpd.conf, vous n’avez pas encore créé cet utilisateur. Dans cette étape, vous allez utiliser l’utilisateur bootstrap comme modèle pour votre nouvel utilisateur. Pour ce faire, vous utiliserez l’outil snmpusm, qui sert à la gestion des utilisateurs.

      Sur le manager server, vous pouvez créer l’utilisateur à partir du modèle en utilisant l’outil snmpusm et la syntaxe générale suivante :

      snmpusm authentication_info agent_server_ip_address create new_user existing_user
      

      En utilisant ce que vous savez sur les indicateurs d’authentification que vous devez passer, et en exploitant le compte d’utilisateur que vous avez déjà (bootstrap), vous pouvez créer un utilisateur qui correspond aux privilèges d’utilisateur que vous avez déjà définis (demo).

      La commande ressemblera à ceci :

      • snmpusm -u bootstrap -l authPriv -a MD5 -x DES -A temp_password -X temp_password agent_server_ip_address create demo bootstrap

      Vous recevrez le message suivant :

      Output

      User successfully created.

      Vous disposez maintenant d’un utilisateur pleinement fonctionnel appelé demo sur votre agent server. Toutefois, il utilise toujours les mêmes informations d’authentification que le compte bootstrap. Pour augmenter la sécurité, vous pouvez modifier le mot de passe. Cette fois, vous utiliserez le compte demo pour vous authentifier. N’oubliez pas que les mots de passe doivent contenir au moins huit caractères :

      • snmpusm -u demo -l authPriv -a MD5 -x DES -A temp_password -X temp_password agent_server_ip_address passwd temp_password new_password

      Vous recevrez le message suivant :

      Output

      SNMPv3 Key(s) successfully changed.

      Vous pouvez tester vos nouveaux identifiants et mot de passe en demandant à l’agent server depuis combien de temps le service SNMP fonctionne. Vous utiliserez la commande snmpget pour obtenir une seule valeur depuis l’agent server.

      Cette fois, profitez des définitions MIB supplémentaires que vous avez téléchargées pour demander la valeur par nom au lieu de l’identifiant numérique OID.

      • snmpget -u demo -l authPriv -a MD5 -x DES -A new_password -X new_password agent_server_ip_address sysUpTime.0

      Vous récupérerez une valeur qui représente la dernière fois que le démon SNMP distant a été redémarré :

      Output

      DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (53309) 0:08:53.09

      Vous disposez maintenant d’un compte utilisateur qui fonctionne nommé demo. Dans l’étape suivante, vous allez simplifier le travail avec les commandes SNMP en configurant le client.

      Étape 6 – Création d’un fichier de configuration client

      Vous avez probablement remarqué à ce stade que les détails d’authentification pour toutes vos commandes SNMP seront assez statiques à chaque requête. Au lieu de les saisir à chaque fois, vous pouvez créer un fichier de configuration côté client qui contiendra les informations d’identification avec lesquelles vous vous connectez.

      Le fichier de configuration client peut être placé à deux endroits différents en fonction de la diffusion que vous souhaitez lui donner.

      Si vous souhaitez partager vos identifiants de connexion avec tout utilisateur valide sur votre machine de gestion, vous pouvez placer vos détails de configuration dans le fichier global snmp.conf sur le manager server. Vous devez ouvrir ce fichier avec les privilèges sudo :

      • sudo nano /etc/snmp/snmp.conf

      Toutefois, si vous souhaitez définir les données d’authentification pour votre seul utilisateur, vous pouvez créer un répertoire .snmp caché dans le répertoire de base de votre utilisateur sur le manager server, et y créer le fichier :

      • mkdir ~/.snmp
      • nano ~/.snmp/snmp.conf

      Quelle que soit votre décision quant à l’emplacement de votre configuration, le contenu sera le même.

      Les commandes que vous utiliserez pour vous authentifier figurent dans le tableau suivant. Dans la colonne de droite, vous pouvez voir les noms des directives utilisées pour définir les informations de configuration dans le fichier snmp.conf :

      Indicateur de commande Description Directive snmp.conf traduite
      -u username Le nom d’utilisateur SNMPv3 avec lequel vous devez vous identifier. defSecurityName username
      -l authPriv Le niveau de sécurité pour vous authentifier. defSecurityLevel authPriv
      -a MD5 Le protocole d’authentification à utiliser. defAuthType MD5
      -x DES Le protocole de confidentialité (cryptage) à utiliser. defPrivType DES
      -A passphrase La phrase de passe d’authentification pour le nom d’utilisateur fourni. defAuthPassphrase passphrase
      -X passphrase La phrase de passe de confidentialité pour le nom d’utilisateur fourni. defPrivPassphrase passphrase

      En utilisant ces informations, vous pouvez construire un fichier snmp.conf approprié. Pour ce guide, il ressemblera à ceci :

      snmp.conf

      defSecurityName demo
      defSecurityLevel authPriv
      defAuthType MD5
      defPrivType DES
      defAuthPassphrase new_password
      defPrivPassphrase new_password
      

      Lorsque vous avez terminé, enregistrez et fermez le fichier.

      Maintenant, vous pouvez passer des commandes sans fournir les informations d’authentification. Vous n’aurez besoin que de la commande SNMP, de l’hôte et des arguments de commande.

      Au lieu de saisir :

      • snmpget -u demo -l authPriv -a MD5 -x DES -A new_password -X new_password agent_server_ip_address sysUpTime.0

      Vous pouvez saisir :

      • snmpget agent_server_ip_address sysUpTime.0

      Comme vous pouvez le constater, cela réduit considérablement la quantité d’informations que vous devez fournir dans chaque demande. Ensuite, vous supprimerez le compte bootstrap pour renforcer la sécurité du réseau.

      Étape 7 – Suppression du compte bootstrap

      Maintenant que votre compte ordinaire est correctement configuré, vous pouvez supprimer le compte bootstrap non sécurisé.

      Sur votre agent server, ouvrez à nouveau le fichier /etc/snmp/snmpd.conf avec des privilèges sudo.

      • sudo nano /etc/snmp/snmpd.conf

      Trouvez et commentez (ou supprimez) les deux lignes que vous avez ajoutées précédemment et qui font référence à l’utilisateur bootstrap:

      /etc/snmp/snmpd.conf

      ...
      #createUser bootstrap MD5 temp_password DES
      #rwuser bootstrap priv
      ...
      

      Enregistrez et fermez le fichier.

      Maintenant, redémarrez le démon SNMP :

      • sudo systemctl restart snmpd

      Cela permettra de respecter la recommandation de ne pas avoir de directives createUser dans le fichier snmpd.conf normal. Cela supprimera également les privilèges de cet utilisateur temporaire.

      Si vous souhaitez supprimer complètement l’utilisateur bootstrap de la usmUserTable, vous pouvez le faire en émettant cette commande depuis le manager server :

      • snmpusm agent_server_ip_address delete bootstrap

      Vous recevrez la réponse suivante :

      Output

      User successfully deleted.

      Conclusion

      À ce stade, vous disposez d’une installation client-serveur entièrement configurée qui peut communiquer de manière sécurisée en utilisant le protocole SNMP. Vous pouvez désormais ajouter des démons supplémentaires sur d’autres hôtes et configurer l’accès aux comptes sur l’ensemble de votre infrastructure.

      Pour en savoir plus, vous pouvez utiliser notre tutoriel Comment utiliser la suite d’outils Net-SNMP pour gérer et surveiller les serveurs : vous vous familiariserez avec les outils SNMP et apprendrez à les utiliser pour récupérer des valeurs une par une ou par lot, et à modifier les données.



      Source link