mirror of
git://git.acid.vegas/random.git
synced 2024-11-10 18:16:44 +00:00
274 lines
9.5 KiB
Markdown
274 lines
9.5 KiB
Markdown
A full write-up on OpenSSH usage with security in mind.
|
|
|
|
---
|
|
|
|
# Table of Contents
|
|
* [Generating An SSH Key Pair](#generating-an-ssh-key-pair)
|
|
- [Linux](#linux)
|
|
- [Windows](#windows)
|
|
* [Getting Your Client To Use Your SSH Key](#getting-your-client-to-use-your-ssh-key)
|
|
- [Linux](#linux)
|
|
- [Windows](#windows)
|
|
* [Setup Server](#setup-server)
|
|
- [Harden OpenSSH Daemon](#harden-openssh-daemon)
|
|
- [Create A New User On The Server](#create-a-new-user-on-the-server)
|
|
- [Copy Your Public Key To Your Shell](#copy-your-public-key-to-your-shell)
|
|
* [Extra Security](#extra-security)
|
|
- [Allow Incoming SSH Connections Through IPTables](#allow-incoming-ssh-connections-through-iptables)
|
|
- [Lock Users In A Chroot Jail Environment](#lock-users-in-a-chroot-jail-environment)
|
|
- [Port Knocking](#port-knocking)
|
|
- [Setup Server](#setup-server-1)
|
|
- [Using IPTables](#using-iptables)
|
|
- [Using Knockd](#using-knockd)
|
|
- [Knocking Your Server](#knocking-your-server)
|
|
- [Using Nmap](#using-nmap)
|
|
- [Using knockd](#using-knockd-1)
|
|
- [Jump Hosts](#jump-hosts)
|
|
|
|
**Note:** The port *65150* is used in this write-up as an example of how to use a non-standard ports.
|
|
|
|
---
|
|
|
|
## Generating An SSH Key Pair
|
|
### Linux
|
|
Generate a key using the **Ed25519** algorithm with 500 KDF rounds:
|
|
* `ssh-keygen -t ed25519 -a 500 -C "$(whoami)@$(hostname)-$(date -I)"`
|
|
|
|
This will generate 2 files in your `~/.ssh` directory. A public key *(.pub)* and a private key.
|
|
|
|
You only need to backup your private key. Public keys can be regenerated from the private key:
|
|
* `ssh-keygen -y -f ~/.ssh/acidvegas@pi-2017-01-01`
|
|
|
|
Copy your public key to clipboard:
|
|
* `cat ~/.ssh/acidvegas@pi-2017-01-01.pub`
|
|
|
|
### Windows
|
|
Download & run [puttygen](https://the.earth.li/~sgtatham/putty/latest/w32/puttygen.exe).
|
|
|
|
Once opened, change the key type to **ED25519** under the *Parameters* box, and then click the *Generate* button.
|
|
|
|
Click the *Save private key* button to save your key.
|
|
|
|
You only need to backup your private key. Public keys can be regenerated by clicking `File -> Load private key`.
|
|
|
|
Copy the data in the box labeled *Public key for pasting into OpenSSH authorized_keys file*.
|
|
|
|
## Getting Your Client To Use Your SSH Key
|
|
### Linux
|
|
* `ssh -p 65150 -i ~/.ssh/acidvegas@pi-2017-01-01 acidvegas@192.168.1.10`
|
|
|
|
or...
|
|
|
|
* `nano ~/.ssh/config`
|
|
```
|
|
Host acidbox
|
|
HostName 192.168.1.10
|
|
Port 65150
|
|
User acidvegas
|
|
IdentityFile ~/.ssh/acidvegas@pi-2017-01-01
|
|
IdentitiesOnly yes
|
|
```
|
|
* `chmod 600 ~/.ssh/config`
|
|
* Usage: `ssh acidbox`
|
|
|
|
### Windows
|
|
Download & run the [putty](https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe) client.
|
|
|
|
Once opened, select `Connection -> SSH -> Auth` from the *Category* box. Click the *Browse* button and select your private key.
|
|
|
|
Select *Session* from the *Category* box. Change the *Host Name (or IP address)* and *Port* to your server.
|
|
|
|
Name the session in *Saved Sessions* box and click the *Save* button.
|
|
|
|
SSH into your server by clicking your saved session from the *Saved Sessions* box, and clicking the *Open* button.
|
|
|
|
---
|
|
|
|
## Setup Server
|
|
### Harden OpenSSH Daemon
|
|
* `nano /etc/ssh/sshd_config`
|
|
```
|
|
AddressFamily any
|
|
AllowAgentForwarding no
|
|
AllowGroups ssh
|
|
AllowTcpForwarding no
|
|
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
|
|
#Banner /etc/issue
|
|
ChallengeResponseAuthentication no
|
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
|
ClientAliveInterval 0
|
|
#ClientAliveCountMax 0
|
|
HostKey /etc/ssh/ssh_host_ed25519_key
|
|
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
|
|
LoginGraceTime 30
|
|
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
|
|
MaxAuthTries 2
|
|
MaxSessions 1
|
|
MaxStartups 3:50:10
|
|
PasswordAuthentication no
|
|
PermitRootLogin no
|
|
Port 65150
|
|
PrintLastLog no
|
|
PrintMotd no
|
|
Protocol 2
|
|
```
|
|
* `mkdir /etc/ssh/authorized_keys`
|
|
* `rm /etc/ssh/ssh_host_*_key`
|
|
* `ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key`
|
|
|
|
**Options**:
|
|
* The `AddressFamily` option can be:
|
|
- **inet** for IPv4 only.
|
|
- **inet6** for IPv6 only.
|
|
- **any** for both.
|
|
* The `AuthorizedKeysFile` option can be commented out to use the standard `~/.ssh/authorized_keys` file instead.
|
|
* The `Banner` option can be un-commented if the `/etc/issue` file exists. This is shown before the user authenticates.
|
|
* The `ClientAliveCountMax` option can be un-commented & the `ClientAliveInterval` option can be changed to **1800** to enforce a 15 minute idle timeout.
|
|
* The `MaxSessions` option can be increased if there are additional users on the server.
|
|
* The `Port` option should be set to a non-standard port *(High-value port number recommended)*.
|
|
* The `PrintMotd` option can be changed to **yes** if the file `/etc/motd` exists. This is shown after the user authenticates.
|
|
|
|
### Create A New User On The Server
|
|
Create a new user on the server with a password:
|
|
* `useradd -m -s /bin/bash acidvegas`
|
|
* `passwd acidvegas`
|
|
|
|
Create an **ssh** group and add your user to the group.
|
|
* `groupadd ssh`
|
|
* `gpasswd -a acidvegas ssh`
|
|
|
|
### Copy Your Public Key To Your Shell
|
|
* `nano /etc/ssh/authorized_keys/acidvegas` *(Paste your public key data in this file)*
|
|
|
|
**Note:** This is only required if you are using the `AuthorizedKeysFile /etc/ssh/authorized_keys/%u` line in your `sshd_config` file. For using the standard `~/.ssh/authorized_keys` file, do the follow:
|
|
* `mkdir ~/.ssh`
|
|
* `chmod 700 ~/.ssh`
|
|
* `chown -R $USER ~/.ssh`
|
|
* `nano ~/.ssh/authorized_keys` *(Paste the copied public key data into this file)*
|
|
* `chmod 400 ~/.ssh/authorized_keys`
|
|
* Optionally, you can pass the immutable flag to prevent changes:
|
|
- `chattr +i ~/.ssh`
|
|
- `chattr +i ~/.ssh/authorized_keys`
|
|
|
|
---
|
|
|
|
# Extra Security
|
|
### Allow Incoming SSH Connections Through IPTables
|
|
```
|
|
iptables -A INPUT -i eth0 -p tcp --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
|
|
iptables -A OUTPUT -o eth0 -p tcp --sport 65150 -m conntrack --ctstate ESTABLISHED -j ACCEPT
|
|
```
|
|
|
|
You can also allow only incomming connection from a specific IP address instead by changing the first line above to:
|
|
```
|
|
iptables -A INPUT -i eth0 -p tcp -s 192.168.1.99 --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
|
|
```
|
|
|
|
### Lock Users In A Chroot Jail Environment
|
|
See [mkchroot](https://github.com/acidvegas/mkchroot) repository for details.
|
|
|
|
### Port Knocking
|
|
The following is an example which uses the port knocking sequence `8881 -> 7777 -> 9991` to open port 65150 for 30 seconds.
|
|
|
|
##### Server
|
|
###### Using IPTables
|
|
* `nano /etc/iptables/iptables.rules`
|
|
```
|
|
*filter
|
|
:INPUT DROP [0:0]
|
|
:FORWARD DROP [0:0]
|
|
:OUTPUT ACCEPT [0:0]
|
|
:TRAFFIC - [0:0]
|
|
:SSH-INPUT - [0:0]
|
|
:SSH-INPUTTWO - [0:0]
|
|
# TRAFFIC chain for Port Knocking. The correct port sequence in this example is 8881 -> 7777 -> 9991; any other sequence will drop the traffic
|
|
-A INPUT -j TRAFFIC
|
|
-A TRAFFIC -p icmp --icmp-type any -j ACCEPT
|
|
-A TRAFFIC -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 65150 -m recent --rcheck --seconds 30 --name SSH2 -j ACCEPT
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH2 --remove -j DROP
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 9991 -m recent --rcheck --name SSH1 -j SSH-INPUTTWO
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH1 --remove -j DROP
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 7777 -m recent --rcheck --name SSH0 -j SSH-INPUT
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH0 --remove -j DROP
|
|
-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 8881 -m recent --name SSH0 --set -j DROP
|
|
-A SSH-INPUT -m recent --name SSH1 --set -j DROP
|
|
-A SSH-INPUTTWO -m recent --name SSH2 --set -j DROP
|
|
-A TRAFFIC -j DROP
|
|
COMMIT
|
|
```
|
|
* `systemctl daemon-reload `
|
|
* `systemctl restart iptables`
|
|
|
|
###### Using Knockd
|
|
Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
|
|
|
|
* `nano /etc/knockd.conf`
|
|
```
|
|
[options]
|
|
logfile = /var/log/knockd.log
|
|
[opencloseSSH]
|
|
sequence = 8881:tcp,7777:tcp,9991:tcp
|
|
seq_timeout = 5
|
|
tcpflags = syn,ack
|
|
start_command = /usr/bin/iptables -A TCP -s %IP% -p tcp --dport 65150 -j ACCEPT
|
|
cmd_timeout = 10
|
|
stop_command = /usr/bin/iptables -D TCP -s %IP% -p tcp --dport 65150 -j ACCEPT
|
|
```
|
|
|
|
##### Knocking Your Server
|
|
###### Using Nmap
|
|
Download & install the [nmap](https://nmap.org/) package.
|
|
|
|
* `nano knock.sh`
|
|
```bash
|
|
#!/bin/bash
|
|
HOST=$1
|
|
shift
|
|
for ARG in "$@"
|
|
do
|
|
nmap -Pn --host_timeout 100 --max-retries 0 -p $ARG $HOST
|
|
done
|
|
```
|
|
* Usage: `sh knock.sh example.server.com 8881 7777 9991`
|
|
|
|
###### Using Knockd
|
|
Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
|
|
|
|
* `knock -v example.server.com 8881:tcp 7777:tcp 9991:tcp`
|
|
|
|
### Jump Hosts
|
|
* `ssh -J <jumphost> <host>`
|
|
|
|
The `<jumphost>` option can be `user@host`, `user@host:port` or an host setup in your `~/.ssh/config`.
|
|
|
|
Multiple jump hosts can be used in a comma *(no spaces)* separated list.
|
|
|
|
The same applies for the `<host>` option, except to change the port, either use the `-p <port>` option at the end or use a host setup in your `~/.ssh/config`.
|
|
|
|
or...
|
|
|
|
* nano `~/.ssh/config`:
|
|
```
|
|
Host jumpbox
|
|
HostName jump.server.com
|
|
|
|
Host targetbox
|
|
...
|
|
ProxyJump jumpbox1
|
|
...
|
|
```
|
|
|
|
Multiple jump hosts can be used in the `ProxyJump` option in a comma *(no spaces)* separated list.
|
|
|
|
Connect to your target host with `ssh targetbox`
|
|
|
|
---
|
|
|
|
## Sources
|
|
* https://wiki.archlinux.org/index.php/Port_knocking
|
|
* https://wiki.archlinux.org/index.php/SSH_keys
|
|
* https://wiki.mozilla.org/Security/Guidelines/OpenSSH
|
|
* https://www.openssh.com/manual.html
|
|
* https://stribika.github.io/2015/01/04/secure-secure-shell.html
|