среда, 22 мая 2019 г.

Сервер strongswan ipsec + клиенты на Win10 и Ubuntu ч.4: настройка клиента на Ubuntu

1. apt install strongswan
2. В /etc/ipsec.secrets добавляем
<client_ID> <server_ID> : PSK <key>

!Ключ в такой записи добавляем без кавычек!

3. В /etc/ipsec.conf
conn VPN
        dpdaction=restart
        dpddelay=35s
        dpdtimeout=300s
        rekey=no
        left=%any
        leftid=<private_IP>
        right=<public_ip>
        rightsubnet = 0.0.0.0/0
        ike=aes256-sha2_256-modp1024!
        esp=aes256-sha2_256!
        authby=secret
        auto=add
        leftsourceip=%config

       
Комментарии:
- по умолчанию 'left' это локальная сторона. Только если IP адрес или разрешенный FQDN в "right" совпадает с локальным IP адресом стороы меняются местами.
- конфиги dpd - Dead peer detection
- left/right - IP адрес, leftid/rightid - идентификатор, т.е. если клиент за натом в качестве leftid указываем адрес на интерфейсе
- leftsourceip=%config - клиент запросит у сервера виртуальный адрес
- с помощью настроек left/rightsubnet можно организовать split tunnel. В моей конфигурации на leftsubnet на сервере и rightsubnet на клиенте 0.0.0.0/0 т.е. весь трафик заворачивается в туннель


4. Логи.
4.1. Самый простой вариант: на любой стороне можно добавить в /etc/ipsec.conf
config setup
        charondebug="cfg 2, dmn 2, ike 2, net 1"


Тогда в /var/log/syslog будут писаться довольно подробные логи

4.2. Вообще, в strongswan достаточно гибгкий механизм логирования, можно использовать stdout/stderr, файл или syslog
По умолчанию, strongswan не может писать логи в файлы в Убунту (вероятно, эта же проблема не позволяет корректно перехватывать сообщения от strongswan из stderr).
Решение я нашел здесь:
http://tiebing.blogspot.com/2015/10/ubuntu-1404-strongswan-not-logging.html
It turns out that ubuntu uses "AppArmor" to limit where strongswan can write files. You can install apparmor-utils and use the command "aa-complain" to turn strongswan binaries from "enforce" mode to "complain" mode:

# apt-get install apparmor-utils
# aa-status
# aa-complain /usr/lib/ipsec/charon
Setting /usr/lib/ipsec/charon to complain mode.


После применения этого фикса, можно настроить логгирование в в /etc/strongswan.config. Пример (логи пишутся в stdout и /var/log/charon.log):
charon {
    load_modular = yes
    plugins {
        include strongswan.d/charon/*.conf
    }
    filelog {
                /var/log/charon.log {
                        append = no
                        default = 0
            ike = 1
            knl = 1
                        flush_line = yes
                }
        stdout {
            default = 0
            ike = 1
            knl = 1
        }
        }

}


5. Полезные команды:
-перечитать конфиги и перезапустить ipsec:
ipsec reload && ipsec restart

-включить/вылючить конкретное соединение (conn XXXX в ipsec.conf):
ipsec up/down XXXX

-перечитать настройки в ipsec.secrets:
ipsec rereadsecrets

6. Проще всего включать/выключать соединение на клиенте из консоли. Лично мне все графические клиенты показались неудобными.
Если конечный пользователь совсем не дружит с консолью, можно использовать вот этот простой скрипт на Python (для нормальной работы, требуется чтобы charon писал логи в /var/log/charon.log, см. пример выше):

#!/usr/bin/env python3

import subprocess
import time


def execute(cmd):
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    for out_line in popen.stdout:
        yield str(out_line)


started = False
for line in execute(['tail', '-n 1', '-F', '/var/log/charon.log']):
    #print(f'TEST:{line}')
    if not started:
        subprocess.Popen(['sudo', 'ipsec', 'up', 'VPN'], stdout=subprocess.PIPE)
        started = True
    if 'retransmit 2' in line:
        print("Connection timeout. Try again later")
        subprocess.run(['sudo', 'ipsec', 'down', 'VPN'], stdout=subprocess.PIPE)
        time.sleep(3)
        break
    if 'established with SPIs' in line:
        print('Connection established.')
        while True:
            try:
                run = input('Ctrl+C to terminate\n')
            except KeyboardInterrupt:
                print('\nClosing connection')
                subprocess.run(['sudo', 'ipsec', 'down', 'VPN'], stdout=subprocess.PIPE)
                time.sleep(3)
                break

Сервер strongswan ipsec + клиенты на Win10 и Ubuntu ч.3: Настройка клиента на Win10

Здесь все просто:

1. Создаем vpn подключение на клиентском ПК, включаем обязательное шифрование.




2. Импортируем корневой сертификат (caCert.der)в доверенные корневые центры сертификации локального компьютера.

3. Отключаем Split Tunnel на клиентском ПК, чтобы получить маршрут по умолчанию через VPN (Powershell):
Set-VpnConnection –Name 'Test' –SplitTunneling $false 

4. После очередного обновления strongswan пришлось подкрутить настройки VPN на Windows, чтобы при подключении использовались приемлемые для strongswan параметры: https://docs.microsoft.com/en-us/powershell/module/vpnclient/set-vpnconnectionipsecconfiguration?view=win10-ps  

Сервер strongswan ipsec + клиенты на Win10 и Ubuntu ч. 2: Настройка iptables на сервере

1. Перед настройкой IPtables запланировать перезагрузку через 10 минут, чтобы не потерять доступ, если что-то пойдет не так:

shutdown -t 10 –r

Отменить перезагрузку:
shutdown –c 

2. Создаем скрипт для iptables (не забываем chmod 0740)
nano /usr/local/firewall/firewall_static.sh

3. Правила:
#!/bin/sh

PATH='/sbin'
ALLOW_SSH='<ip_addresses>'
ALLOW_VPN='<ip_addresses>'
WAN='<int_name>'
IPSEC_NET='<network>'

# Flush previous rules, delete chains and reset counters
iptables -F
iptables -X
iptables -Z
iptables -t nat -F

# Default policies
iptables -P FORWARD DROP
iptables -P INPUT   DROP
iptables -P OUTPUT  DROP

echo -n '1' > /proc/sys/net/ipv4/ip_forward
echo -n '0' > /proc/sys/net/ipv4/conf/all/accept_source_route
echo -n '0' > /proc/sys/net/ipv4/conf/all/accept_redirects
echo -n '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo -n '1' > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# Enable loopback traffic
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Enable statefull rules (after that, only need to allow NEW conections)
iptables -A INPUT   -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT


# Drop invalid state packets
iptables -A INPUT   -m conntrack --ctstate INVALID -j DROP
iptables -A OUTPUT  -m conntrack --ctstate INVALID -j DROP
iptables -A FORWARD -m conntrack --ctstate INVALID -j DROP

# Allow SSH management
iptables -A INPUT -i $WAN -s $ALLOW_SSH -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
# Enable all outgoing traffic to internet
iptables -A OUTPUT -o $WAN -d 0.0.0.0/0 -j ACCEPT


#Allow incoming IKE connections
iptables -A INPUT -i $WAN -p esp -s $ALLOW_VPN -j ACCEPT
iptables -A INPUT -i $WAN -p ah -s $ALLOW_VPN -j ACCEPT
iptables -A INPUT -i $WAN -p udp -m udp --sport 500 --dport 500 -s $ALLOW_VPN -j ACCEPT
iptables -A INPUT -i $WAN -p udp -m udp --sport 4500 --dport 4500 -s $ALLOW_VPN -j ACCEPT

#Adjust TCP MSS
iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360


#Allow forwarding for VPN
iptables -A FORWARD -s $IPSEC_NET -d 0.0.0.0/0 -i $WAN -m policy --dir in --pol ipsec --reqid 1 --proto esp -j ACCEPT
iptables -A FORWARD -s $IPSEC_NET -d 0.0.0.0/0 -o $WAN -m policy --dir out --pol ipsec --reqid 1 --proto esp -j ACCEPT

#Configure NAT for VPN users
iptables -t nat -A POSTROUTING -s $IPSEC_NET -o $WAN -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s $IPSEC_NET -o $WAN  -j MASQUERADE

## LOGGING to /var/log/messages
#iptables -A INPUT   -j LOG --log-level debug --log-prefix '[FW INPUT]:    '
#iptables -A OUTPUT  -j LOG --log-level debug --log-prefix '[FW OUTPUT]:   '
#iptables -A FORWARD -j LOG --log-level debug --log-prefix '[FW FORWARD ]: '


4. Создаем также правила для ipv6 в файле /usr/local/firewall/ipv6_firewall.sh
(не забываем chmod 0740)
#!/bin/sh
PATH='/sbin'

# Flush the tables to apply changes
ip6tables -F

#ACCEPT POLICY
ip6tables -P INPUT DROP #If it doesn't match a rule Drop it
ip6tables -P FORWARD DROP #NO ROUTING POLICY DROP
ip6tables -P OUTPUT ACCEPT #If it doesn't match a rule

########
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -m state --state ESTABLISHED,RELATED -A INPUT -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT

5. Добавляем . /usr/local/firewall/firewall_static.sh и ./usr/local/firewall/ipv6_firewall.sh
в /etc/rc.local перед exit0

6. Проверяем счетчики iptables
iptables -vL
iptables -t nat -L -n -v

7. Смотрим загрузку интерфейсов
iftop

вторник, 21 мая 2019 г.

Сервер strongswan ipsec + клиенты на Win10 и Ubuntu ч. 1: Настройка strongswan на сервере


Авторизация виндовых клиентов будет происходить по EAP, клиентов на Убунту - с помощью PSK.

1. Устанавливаем необходимые пакеты:
apt-get install strongswan libcharon-extra-plugins dnsmasq

Дополнительно для debian9: apt-get install strongswan-pki

2. Генерируем сертификаты. Можно пойти правильным путем и получить "честные" сертификаты у центра сертификации, типа Comodo. В данном случае вариант бюджетный - самоподписанные сертификаты. В принципе, они ничем не хуже, кроме того, что каждую клиентскую машину нужно настраивать вручную, для того, чтобы она доверяла нашей CA.

2.1 Закрытый ключ для CA
mkdir cert
cd cert
ipsec pki --gen > caKey.der


2.2 Генерируем самоподписанный сертификат CA
ipsec pki --self --in caKey.der --dn "C=CH, O=MyVPN, CN=MyVPN CA" --ca > caCert.der


2.3 Генерируем закрытый ключ сервера
ipsec pki --gen  > peerKey.der


2.4 Генерируем сертификат для сервера
ipsec pki --pub --in peerKey.der | ipsec pki --issue --flag serverAuth --san <server_IP_or_FQDN> --cacert caCert.der --cakey caKey.der \
--dn "C=CH, O=MyVPN, CN=MyVPNServer" > peerCert.der


*для Windows обязательный аргумент --san, он должен совпадать с реальным IP адресом сервера, или его FQDN

2.5 Копируем сгенерированные файлы в соответствующие директории:
/etc/ipsec.d/private/peerKey.der
хранит закрытый ключ узла. Загрузку данного ключа следует настроить в ipsec.secrets
/etc/ipsec.d/certs/peerCert.der
хранит end-entity сертификат узла. Следует указать в ipsec.conf чтобы использовать.
/etc/ipsec.d/cacerts/caCert.der 
хранит CA сертификат с помощь. которого были выпущены и подписаны клиентские сертификаы. Загружается автоматически.

3 Добавляем конфигурацию для клиентов на Windows:
3.1 В /etc/ipsec.conf:
conn win10
        dpdaction=clear
        dpddelay=35s
        dpdtimeout=300s
        fragmentation=yes
        rekey=no

        #left = server side
        left=%any
        leftsubnet=0.0.0.0/0
        leftcert=peerCert.der
        leftfirewall=yes
        leftsendcert=always

        right=%any
        rightsourceip=10.1.1.2/32
        rightdns=8.8.8.8
        eap_identity=%identity
        rightauth=eap-mschapv2
        keyexchange=ikev2
        auto=add


3.2 В /etc/ipsec.secrets
: RSA peerKey.der
test : EAP "abcd1234"


4 Добавляем конфиг для клиентов на Ubuntu: 
4.1 В /etc/ipsec.conf: 
conn ubnt
        dpdaction=restart
        dpddelay=35s
        dpdtimeout=300s
        rekey=no

        left=<public_ip>
        leftid=<public_ip>       
        leftsubnet=0.0.0.0/0
        leftfirewall=yes

        right=<public_ip>
        rightid=<private_ip>
        rightdns=8.8.8.8
        rightsourceip=10.1.1.3/32
        ike=aes256-sha2_256-modp1024!
        esp=aes256-sha2_256!

        authby=secret
        auto=add


4.2 В /etc/ipsec.secrets  
<client_ID> <server_ID> : PSK <key>

*в такой форме записи ключ указывается без кавычек! 

Некоторые комментарии:
 -в моем сценарии клиент за NAT-ом поэтому в качестве аргумента 'left' используется его публичный адрес, в качестве 'left id' - серый адрес.
 - leftfirewall=yes необходимо, если на сервере настроен NAT 
- rightsourceip - виртуальный адрес, который будет выдаваться клиенту. Можно указать целую подсеть, если клиентов много.