воскресенье, 5 июня 2016 г.

Как я создавал свой домашний анонимайзер

Истерия относительно анонимности и безопасности сети мне кажется несколько раздутой. Поэтому я преследовал чисто техническую идею реализации собственного анонимайзера, а не желание скрыть все и вся от чужих глаз.
Итак, задача такова - получить доступ к ресурсам сети Интернет с адреса, отличного от адреса, который мне предоставил локальный провайдер сети Интернет.
Вариантов реализации существует масса - аплеты для браузеров, публичные прокси, включение турбо режима в браузере, анонимные VPN сервера, TOR и т.д.
Но практически во всех случаях в процессе участвует сторонний сервис, на котором нужно регистрироваться, запускать на компе стороннее ПО и другие заморочки.
После некоторого осмысливания вариантов становился на варианте - покупка в минимальной конфигурации серверного контейнера VPS (установка VPN сервера), плюс домашний роутер в качестве VPN клиента.
В качестве хостера контейнера выбрал host1plus (вариантов VPS хостеров тоже море)

    256MB ОЗУ
    20GB Диск
    0.5 Core
    500GB Трафик в месяц
    Фиксированный белый адрес

Цена за месяц $2.5.
В качестве ОС CentOS 6 x86. В качестве домашнего роутера Mikrotik.
В качестве VPN сервера - OpenVPN. Вначале поставил PPTP, но наблюдались проблемы с GRE пакетами, хотя конечно, практически в любой ОС и в любом роутере есть нативный клиент для PPTP.
Иии, газ до упора, а там поглядим, приступим.
1.Подключаюсь к консоли сервера (использую putty), ставлю mc, создаю правила для пакетного фильтра (прикрыться не грех):
-----------------------------------------------------------------------------------
#!/bin/sh

ipt="/sbin/iptables"

$public_eth1="venet0" #Здесь имя сетевого интерфеса моей системы

logger -t rc.local "FW Start..."
echo "FW Start..."

$ipt -t filter -F
$ipt -t nat -F
$ipt -t mangle -F
$ipt -t filter -X
$ipt -t nat -X
$ipt -t mangle -X
$ipt -Z

$ipt -P INPUT DROP
$ipt -P OUTPUT ACCEPT
$ipt -P FORWARD DROP

if [ -e /proc/sys/net/ipv4/conf/all/accept_source_route ]; then
    for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do
        echo "Disable source routing of packets: $i"
        echo "0" > $i;
   done
fi

if [ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ]; then
    echo "Ignore any broadcast icmp echo requests"
    echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
fi

if [ -e /proc/sys/net/ipv4/ip_forward ]; then
    echo "Enable IP Forwarding"
    echo "1" > /proc/sys/net/ipv4/ip_forward
else
    echo "Uh oh: /proc/sys/net/ipv4/ip_forward does not exist"
    echo "(That may be a problem)"
    echo
fi


#Loopback trafic
$ipt -t filter -A INPUT -i lo -j ACCEPT

$ipt -N in_packets
$ipt -N in_public_if
$ipt -N in_vpn_if
$ipt -N fwd_packets
$ipt -N fwd2public4vpn
$ipt -N fwd2vpn4public

echo "All output pakets"
$ipt -A OUTPUT -j ACCEPT


echo "All input pakets"
$ipt -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "inpt:ALL FIN,URG,PSH "
$ipt -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$ipt -A INPUT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "inpt:ALL ALL "
$ipt -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
$ipt -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "inpt:ALL SYN,RST,ACK,FIN,URG "
$ipt -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$ipt -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "inpt:ALL NONE "
$ipt -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
$ipt -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "inpt:SYN,RST SYN,RST "
$ipt -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "inpt:SYN,FIN SYN,FIN "
$ipt -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$ipt -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST  RST  -m limit --limit 15/minute -j in_packets

$ipt -A INPUT -j in_packets
$ipt -A INPUT -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "input: "
$ipt -A INPUT -j REJECT

echo "All forward"
$ipt -A FORWARD -j fwd_packets
$ipt -A FORWARD -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "forward: "
$ipt -A FORWARD -j REJECT

echo "Input pakets on interface"
$ipt -A in_packets -i $public_eth1 -j in_public_if
$ipt -A in_packets -i $public_eth1 -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "in_public_if: "
$ipt -A in_packets -i $public_eth1 -j REJECT

$ipt -A in_packets -i tun0 -j in_vpn_if
$ipt -A in_packets -i tun0 -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "in_tun0_if: "
$ipt -A in_packets -i tun0 -j REJECT

echo "From vpn to public"
$ipt -A fwd_packets -i tun0 -o $public_eth1 -j fwd2public4vpn
$ipt -A fwd_packets -i tun0 -o $public_eth1 -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "fwd2public4vpn: "
$ipt -A fwd_packets -i tun0 -o $public_eth1 -j REJECT

echo "From public to vpn"
$ipt -A fwd_packets -o tun0 -i $public_eth1 -j fwd2vpn4public
$ipt -A fwd_packets -o tun0 -i $public_eth1 -m limit --limit 60/minut --limit-burst 180 -j LOG --log-prefix "fwd2vpn4public: "
$ipt -A fwd_packets -o tun0 -i $public_eth1 -j REJECT


echo "Input pakets"
echo "Input pakets on eth public"
$ipt -A in_public_if -p udp --sport domain --dport $public_port -j ACCEPT
$ipt -A in_public_if -p tcp --sport domain --dport $public_port ! --syn -j ACCEPT
$ipt -A in_public_if -p tcp --sport $public_port --dport auth -j REJECT
$ipt -A in_public_if -p tcp --sport $public_port -m multiport --dports ssh,443 -j ACCEPT
$ipt -A in_public_if -p tcp --dport $public_port -m multiport --sports ftp,ftp-data,http,https -j ACCEPT
$ipt -A in_public_if -p icmp -j ACCEPT

echo "Input pakets on vpn int"
$ipt -A in_vpn_if -p tcp --sport $public_port -m multiport --dports ssh -j ACCEPT
$ipt -A in_vpn_if -p icmp -j ACCEPT

echo "Pakets forward"
echo "From vpn to public"
$ipt -A fwd2public4vpn -j ACCEPT

echo "From public to vpn"
$ipt -A fwd2vpn4public -j ACCEPT

echo "MASQUERADE"
$ipt -t nat -A POSTROUTING -s 10.1.0.0/24 -o $public_eth1 -j MASQUERADE
-----------------------------------------------------------------------------------

В родном репозитарии CentOS нет OpenVPN поэтому подключаю репозитарий внешний и ставлю OpenVPN:

-----------------------------------------------------------------------------------
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.i686.rpm
rpm -i rpmforge-release-0.5.3-1.el6.rf.i686.rpm
yum update
yum install -y openvpn
-----------------------------------------------------------------------------------

Конфиг сервера в /etc/openvpn/server.conf

-----------------------------------------------------------------------------------
dev tun
port 443
proto tcp
server 10.1.0.0 255.255.255.248
management 127.0.0.1 23

ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh dh1024.pem

status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log
verb 3
persist-tun
persist-key

user root
group nobody

duplicate-cn

username-as-common-name
plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so "login login USERNAME password PASSWORD"

#comp-lzo

topology subnet

sndbuf 0
rcvbuf 0

keepalive 10 120
max-clients 50
ping-timer-rem
inactive 1800

push "sndbuf 393216"
----------------------------------------------------------------------------------

для работы сервера требуются сертификаты для сервера и клиента, но расписывать здесь про это смысла нет - в инете полно примеров создания сертификатов для OpenVPN.
Необходимо создать каталог для логов сервера: /var/log/openvpn
Запускаю сервер  service openvpn start, ошибок нет, сервер запустился и ждет подключений.

2.Теперь очередь Mikrotik. Железка приятная для меня по многим показателям. Надежен, производителен, удобен в настройке и управлении.
Импортирую клиентский сертификат, затем клиентский ключ.

С клиентским сертификатом все. Теперь нужно создать клиентский интерфейс для OpenVPN сервера:

В поле "Connect To:" указываю IP адрес на котором поднят мой OpenVPN сервер.
Если отметить "Add Default Route", то весь трафик будет уходить через созданный интерфейс, но это не всегда удобно, на мой взгляд, удобнее создать дополнительные правила маршрутизации, например по источнику или по цели или использовать маркировку пакетов.
Например, нужно сделать чтобы хост с адресом 192.168.1.20 шел в Интернет через анонимайзер, а остальные стандартным образом. Создаю правило для маршрутизации:

И дополнительный маршрут, который использует таблицу маршрутизации my-host:

Теперь хост с адресом 192.168.1.20 будет общаться с внешним миром через анонимайзер.
Если же необходимо использовать анонимайзер для определенного серверов в сети Интернет (например 2.3.4.5), то правило маршрутизации будет выглядеть следующим образом:

И последним пунктом - необходимо включить маскарадинг на клиентском интерфейсе: