OpenSSH is the implementation of the SSH protocol on Ubuntu. OpenSSH is recommended for remote login, making backups, remote file transfer via scp or sftp, and much more. SSH is perfect to keep confidentiality and integrity for data exchanged between two networks and systems. However, the main advantage is server authentication, through the use of public key cryptography.
Here are a few things you need to tweak in order to improve OpenSSH server security:
Before making any modifications to the /etc/sshd_config file, make a backup by:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.factory-defaults
...and
sudo chmod a-w /etc/ssh/sshd_config.factory-defaults
NOTE: Not all of the possible changes mentioned below have to be made. Some changes are not recommended to be made but may offer tighter security depending on your requirements.
Further documentation about SSH can be found at: Ubuntu SSH help.
Issue the command man sshd_config for further details about the server configuration file.
Default SSH Config Files and SSH Port:
Config File | Description |
---|---|
/etc/ssh/sshd_config | OpenSSH server configuration file |
/etc/ssh/ssh_config | OpenSSH client configuration file |
~/.ssh/ | Users SSH configuration directory |
~/.ssh/authorized_keys or ~/.ssh/authorized_keys | Lists the public keys (RSA or DSA) that can be used to log into the user’s account |
/etc/nologin | If this file exists, sshd refuses to let anyone except root to log in |
/etc/hosts.allow and /etc/hosts.deny | Access controls lists that should be enforced by tcp-wrappers are defined here |
SSH default port | 22 |
Once you have finished editing the /etc/ssh/sshd_config file, make sure to save your changes before restarting your SSH daemon.
Issue the following command:
sudo vi /etc/ssh/sshd_config
…add in this line if not already in the sshd configuration file, otherwise modify it to be:
Protocol 2
SSH protocol version 1 (SSH-1) has man-in-the-middle attacks problems and security vulnerabilities. SSH-1 is obsolete and should be avoided at all cost.
…add in this line if not already in the sshd configuration file, otherwise modify it to be:
ServerKeyBits 2048
This defines the number of bits in the ephemeral protocol version 1 server key.
NOTE: The file /etc/ssh/moduli file contains a list of all keys supported.
A recommendation is to remove the smaller groups from the /etc/ssh/moduli file on the server.
When the client asks for a Diffie-Hellman group, sshd searches the moduli file for groups and picks one at random from the set at least as large as what the client requested. If there are no small (eg 1k, 1.5k) keys, then sshd will always use larger ones.
Change the following line in the sshd config file from:
ListenAddress 0.0.0.0
to
ListenAddress 192.168.0.11
Allowing connections from only certain IP addresses makes a system a lot more secure.
It's recommended to change the listening address.
Change the following line in the sshd config file from:
PermitRootLogin yes
to
PermitRootLogin no
By default, the SSH daemon ships with remote root logins enabled. Normally Ubuntu does not allow direct access to the root user, so this setting is unimportant. If you have set a password on the root account, this setting can be a potential security risk, and should be disabled.
It is safer to login as another user and use sudo.
NOTE: Sometimes it is necessary to allow root logins when doing automated tasks such as backups. To disallow normal logins but allow forced commands, you can use:
PermitRootLogin forced-commands-only
…add in this line if not already in the /etc/ssh/sshd_config file, otherwise modify it to be:
PermitEmptyPasswords no
You need to explicitly disallow remote login from accounts with empty passwords.
Change the following line in the /etc/ssh/sshd_config file from:
LogLevel INFO
to
LogLevel VERBOSE
By default, the OpenSSH server logs to the AUTH facility of syslog, at the INFO level. To record more information - such as failed login attempts - increase the logging level to VERBOSE.
Now all the details of ssh login attempts will be saved in your /var/log/auth.log file.
If you have started using a different port, or if you think your server is well-enough hidden not to need much security, you should increase your logging level and examine your /var/log/auth.log file every so often. If you find a significant number of spurious login attempts, then your computer is under attack and you need more security.
Whatever security precautions you've taken, you might want to set the logging level to VERBOSE for a week, and see how much spurious traffic you get. It can be a sobering experience to see just how much your computer gets attacked.
It's recommended to log more information if you're curious about malicious SSH traffic.
Add the following lines to the sshd config file:
ClientAliveInterval 900
ClientAliveCountMax 1
You are setting an idle timeout interval in seconds (900 secs = 15 minutes). After this interval has passed, the idle user will be automatically logged out.
PCI-DSS requires that there be a maximum of 1 concurrent SSH session per user.
…add in this line if not already in the sshd configuration file, otherwise modify it to be:
IgnoreRhosts yes
SSH can emulate the behavior of the obsolete rsh command. Therefore disable access via rsh. To ensure that SSH does not read the user's ~/.rhosts and ~/.shosts files.
It's recommended to disable rsh access.
…add in this line if not already in the sshd configuration file, otherwise modify it to be:
AddressFamily inet
Specifically limit traffic to IPv4. This will limit attack vectors.
The options that can be used for this line are:
It's recommended to limit the system to IPV4 if IPV6 is not used on the system.
Change the following line in the sshd config file from:
#Banner /etc/issue.net
to
Banner /etc/issue.net
Now, edit /etc/issue.net and place a warning to unauthorized users. An example of what to include is shown here:
***************************************************************************
NOTICE TO USERS
This computer system is the private property of its owner, whether
individual, corporate or government. It is for authorized use only.
Users (authorized or unauthorized) have no explicit or implicit
expectation of privacy.
Any or all uses of this system and all files on this system may be
intercepted, monitored, recorded, copied, audited, inspected, and
disclosed to your employer, to authorized site, government, and law
enforcement personnel, as well as authorized officials of government
agencies, both domestic and foreign.
By using this system, the user consents to such interception, monitoring,
recording, copying, auditing, inspection, and disclosure at the discretion
of such personnel or officials. Unauthorized or improper use of this
system may result in civil and criminal penalties and administrative
or disciplinary action, as appropriate. By continuing to use this system
you indicate your awareness of and consent to these terms and
conditions of use. LOG OFF IMMEDIATELY if you do not agree to the
conditions stated in this warning.
****************************************************************************
Once this is in place, restart sshd and all users will see this warning before they get the login prompt.
The SSH daemon will allow a message to be displayed to users attempting to log in to the SSH server.
To enable login messages, remove the hash sign # from the Banner line.
For legal reasons, it can be useful to display a banner informing people about their legal rights with regards to your server.
This will obviously not dissuade automated SSH attacks, and will potentially worsen Denial-of-Service (DoS) effects, but it may tip off a human attacker that the system is being looked after closely, and that they should move on to some other system on the network.
Create a group called sshusers and only add users to it who require remote access.
Issue the following command:
sudo groupadd sshusers
…and add users to the group who are allowed to access ssh:
sudo usermod -a -G sshusers peter
Alternatively edit the /etc/group file:
sudo vi /etc/group
...and edit the sshusers line as follows:
sshusers:x:1002:peter, john, james, SHAREWIZ\SWAdmin, SHAREWIZ\peter.roux
NOTE: Besides groups, individual users can also be allowed to access SSH.
As can be seen from the above example, the last few usernames show Active Directory logins. Information on Active Directory can be found elsewhere on this site.
Edit the /etc/ssh/sshd_config file:
sudo vi /etc/ssh/sshd_config
Add in the following line:
AllowGroups sshusers
By default, SSH will permit every user with a UNIX account to be able to log in.
You can explicitly allow or deny access for certain users or groups.
An alternative to using AllowGroups is to use the AllowUsers and DenyUsers directives to modify the access rights of these users.
Examples:
To allow access to users username1 and username2, add the following:
AllowUsers username1 username2
To limit access to a specific user from a specific IP address, use something like:
AllowUsers username@192.168.0.2 username2
To deny access to specific users, add the following:
DenyUsers username3 username4 username5
IMPORTANT: If using Active Directory logins, remember to add in these users to the sshusers group as well. So in /etc/group, add in users such as:
SHAREWIZ\peter.roux
To prevent slow SSH connections, disable DNS checking for SSH.
…add in this line if not already in the sshd configuration file, otherwise modify it to be:
useDNS no
This can be re-enabled at a later stage once DNS is configured.
Change the following line in the sshd config file from:
LoginGraceTime 120
to
LoginGraceTime 60
By default, OpenSSH gives you two minutes to type a password in once you've connected. You might want to change this if you are worried about attackers, but need to allow passwords.
This doesn't add much security, but also doesn't make it much harder to legitimately use SSH.
Security can be tightened by forcing public key authentication and disabling password authentication entirely. While this greatly enhances security and completely defeats brute-force attacks, it will lock you out of the machine if you lose your private key. Use with caution!
On the client, generate a key pair with a strong passphrase using:
sudo ssh-keygen -t rsa -b 4096
which will display:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/<username>/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/<username>/.ssh/id_rsa.
Your public key has been saved in /home/<username>/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx <username>@<client hostname>
Next, copy the above key to the server you'd like to login to (NOTE: This puts the key in /home/<username>/.ssh/authorized_keys on the server):
ssh-copy-id -i /home/<username>/.ssh/id_rsa.pub <username>@<server hostname>
Verify you can login to the server with your new key:
ssh <username>@<server hostname>
which will prompt:
Enter passphrase for key '/home/ <username>@<server hostname:~$
Once you have verified you can login to the server with your new key pair, update /etc/ssh/sshd_config on the server to have Password Authentication disabled.
# Change to disable tunnelled clear text passwords:
#PasswordAuthentication yes
to
PasswordAuthentication no
Change the following line in the sshd config file from:
Subsystem sftp /usr/lib/openssh/sftp-server
to
Subsystem sftp internal-sftp
Add a stanza like the following to the *bottom* of the same file. NOTE: It must be at the bottom, because Match groups are only terminated by the end of the file (or another Match stanza):
Match User peter
ChrootDirectory %h/public_html
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
Suppose you want to give some users the ability to upload and download files from their home directories (or ~/public_html), but not a full shell account. This is simple to achieve with OpenSSH's SFTP component.
Now peter can use SFTP to read from and write to his ~/public_html/ directory, but can't use OpenSSH to get a shell, nor even to read files outside of ~/public_html.
If you have many such users, you can change User peter to `Group sftponly, and add users to the sftponly group using usermod(8)`. For FTP on such systems, consider vsftpd: it is more security-conscious than other FTP implementations.
Issue the following command:
...which should show something like:
root@server1:~# netstat -na|grep tcp tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 192.168.0.11:22 192.168.0.184:39662 ESTABLISHED tcp6 0 0 :::22 :::* LISTEN
The
The 2nd line can be ignored. This is simply the current connection.
Similarly, the
Execute the following command:
sudo service ssh restart
Alternatively use the old-fashioned method to restart the service:
sudo /etc/init.d/ssh restart
Issue the following command:
...which should show something like:
root@server1:~# netstat -na|grep tcp tcp 0 0 192.168.0.11:22 0.0.0.0:* LISTEN tcp 0 0 192.168.0.11:22 192.168.0.184:39662 ESTABLISHED
This now shows that SSH is listening on
First, check that the SSH daemon is running:
sudo ps -A | grep sshd
This command should produce a line(s) like this:
<some number> ? 00:00:00 sshd
If there is no line, your SSH daemon is not running. If it is, you should next check that it's listening for incoming connections:
sudo netstat --inet -lpn | grep sshd
This command should produce a line that looks like this:
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN <same number>/sshd
If there is more than one line, then your SSH daemon is listening on more than one port - you might want to go back and delete some Port lines in your sshd_config file.
If there are no lines, your SSH daemon isn't listening on any ports, so you need to add at least one Port line. If the line specifies something other than "0.0.0.0:22", then your SSH daemon is listening on a non-standard port or address, which you might want to fix.
Next, try logging in from your own computer:
sudo ssh -v localhost
...which should show something like:
root@server1:~# sudo ssh -v localhost OpenSSH_6.2p2 Ubuntu-6ubuntu0.1, OpenSSL 1.0.1e 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: Connecting to localhost [127.0.0.1] port 22. debug1: connect to address 127.0.0.1 port 22: Connection refused ssh: connect to host localhost port 22: Connection refused
Notice that the connection was refused. This is due to the earlier config that limited access only from 192.168.0.11. In this case, that allowed IP address was not used, and an attempt was made to login using localhost instead.
Lets retry logging in using an allowed IP address:
sudo ssh -v 192.168.0.11
...which should show something like:
root@server1:~# sudo ssh -v 192.168.1.11 OpenSSH_6.2p2 Ubuntu-6ubuntu0.1, OpenSSL 1.0.1e 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: Connecting to 192.168.0.11 [192.168.0.11] port 22. debug1: Connection established. debug1: permanently_set_uid: 0/0 debug1: SELinux support disabled debug1: identity file /root/.ssh/id_rsa type -1 debug1: identity file /root/.ssh/id_rsa-cert type -1 debug1: identity file /root/.ssh/id_dsa type -1 debug1: identity file /root/.ssh/id_dsa-cert type -1 debug1: identity file /root/.ssh/id_ecdsa type -1 debug1: identity file /root/.ssh/id_ecdsa-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 debug1: match: OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr hmac-md5-etm@openssh.com none debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com none debug1: sending SSH2_MSG_KEX_ECDH_INIT debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ECDSA b7:60:9d:55:7e:43:6a:33:f8:b1:57:54:93:4a:b7:b3 The authenticity of host '192.168.0.11 (192.168.0.11)' can't be established. ECDSA key fingerprint is b7:60:9d:55:7e:43:6a:33:f8:b1:57:54:93:4a:b7:b3. Are you sure you want to continue connecting (yes/no)?
This will print a lot of debugging information, and will then prompt whether you want to connect.
Enter yes.
...which should show some additional lines:
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.11' (ECDSA) to the list of known hosts.
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
Write failed: Broken pipe
The Write failed: Broken pipe message is caused by a timeout issue.
You may recall that the login time was limited in the earlier config.
NOTE:This has however added our WAN IP address into the list of known hosts.
Simply rerun by issuing the following command again.
sudo ssh -v 192.168.0.11
...which should show something like:
debug1: Server host key: ECDSA b7:60:9d:55:7e:43:6a:33:f8:b1:57:54:93:4a:b7:b3
debug1: Host '192.168.1.11' is known and matches the ECDSA host key.
debug1: Found key in /root/.ssh/known_hosts:1
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/id_rsa
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Trying private key: /root/.ssh/id_ecdsa
debug1: Next authentication method: password
root@192.168.1.11's password:
Remember that the password will only be accepted if the corresponding user is allowed access in by SSH.
In this case this would not work, as root was not an allowed user.
Try logging in from a valid user's account. For instance to login using peter as the username use:
sudo ssh -v 192.168.0.11 -l peter
...which should show something like:
... peter@192.168.1.11's password: debug1: Authentication succeeded (password). Authenticated to 192.168.1.11 ([192.168.1.11]:22). debug1: channel 0: new [client-session] debug1: Requesting no-more-sessions@openssh.com debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LC_PAPER = en_GB.UTF-8 debug1: Sending env LC_ADDRESS = en_GB.UTF-8 debug1: Sending env LC_MONETARY = en_GB.UTF-8 debug1: Sending env LC_NUMERIC = en_GB.UTF-8 debug1: Sending env LC_TELEPHONE = en_GB.UTF-8 debug1: Sending env LC_IDENTIFICATION = en_GB.UTF-8 debug1: Sending env LANG = en_GB.UTF-8 debug1: Sending env LC_MEASUREMENT = en_GB.UTF-8 debug1: Sending env LC_TIME = en_GB.UTF-8 debug1: Sending env LC_NAME = en_GB.UTF-8 Welcome to Ubuntu 13.10 (GNU/Linux 3.11.0-18-generic x86_64) * Documentation: https://help.ubuntu.com/ System information as of Mon Mar 24 21:38:35 GMT 2014 System load: 0.08 Processes: 117 Usage of /home: 0.4% of 452MB Users logged in: 0 Memory usage: 3% IP address for eth0: 192.168.1.11 Swap usage: 0% IP address for eth1: 192.168.2.1 Graph this data and manage this system at: https://landscape.canonical.com/ Last login: Mon Mar 24 21:38:41 2014 from 192.168.1.184
If nothing happens, you might need to tell your computer's firewall to allow connections on port 22 (See the FireWall Security section).
Once logged in, to leave the SSH command-line, type:
exit
Copyright ShareWiz by Peter Roux