#!/bin/bash # --- Aleksandr Nurk # --- Cybersecurity WORK 1 # - https://stackoverflow.com/questions/818255/what-does-21-mean IPT="/sbin/iptables" RED='\033[0;31m' GREEN='\033[0;32m' NC='\033[0m' LANINT="enp0s3" WANINT="enp0s8" LAN="192.168.77.0" NETMASK="255.255.255.0" SSH_PORT="2223" NETPLAN=$(ls /etc/netplan) SRVIP=$(awk -F. '{print $1"."$2"."$3"."1}' <<< $LAN) SRVIPMASK=$(awk -F. '{ split($0, octets) for (i in octets) { mask += 8 - log(2**8 - octets[i])/log(2); } print mask }' <<< $NETMASK) echo -e "LANINT: ${RED}$LANINT${NC}" echo -e "WANINT: ${RED}$WANINT${NC}" echo -e "LAN: ${RED}$LAN${NC}" echo -e "NETMASK: ${RED}$NETMASK${NC}" echo -e "NETPLAN: ${RED}$NETPLAN${NC}" echo -e "SRVIP: ${RED}$SRVIP${NC}" echo -e "SRVIPMASK: ${RED}$SRVIPMASK${NC}" echo -e "SSH_PORT: ${RED}$SSH_PORT${NC}" # Проверка прав пользователя, для iptables и т.д. нужны root права sudo -n true if [ $? -ne 0 ] then echo -e "${RED}You should have sudo privilege to run this script..${NC}" exit 1 fi # Создайте пользователя: Agapov/123456qwertY с домашней директорией, /bin/bash и группу sudo USERNAME_="agapov" PASSWORD_="123456qwertY" echo -e "${GREEN}Creating user $USERNAME_..${NC}" useradd -m -p $(openssl passwd -1 ${PASSWORD_}) -s /bin/bash -G sudo ${USERNAME_} echo "$USERNAME_ ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers # Завершать работу скрипта при любой ошибке # set -eu -o pipefail # Открываемся на время обновления $IPT -F $IPT -P INPUT ACCEPT $IPT -P OUTPUT ACCEPT # Проверка соединения и обновления, при ошибке - завершаем работу скрипта ping -c 1 -q google.com &> /dev/null if [ $? -eq 0 ] then echo -e "${GREEN}Installing the must-have pre-requisites..${NC}" # full silent : sudo apt -y -qq upgrade &> /dev/null sudo apt update && sudo apt -y -qq -o Dpkg::Use-Pty=0 upgrade # Tweaks pro config set apt_news=false > /dev/null sudo apt install -y -qq -o Dpkg::Use-Pty=0 ipset isc-dhcp-server fail2ban net-tools sudo apt autoremove -y sleep 1 else echo -e "${RED}Check internet connections..${NC}" exit 1 fi # Настройка dhcp if [ -f "/etc/dhcp/dhcpd.conf" ] then echo -e "${GREEN}Setting up dhcp..${NC}" DHCP_START=$(awk -F. '{print $1"."$2"."$3"."3}' <<< $LAN) DHCP_END=$(awk -F. '{print $1"."$2"."$3"."100}' <<< $LAN) if ! grep -Fwiq "subnet $LAN netmask $NETMASK" /etc/dhcp/dhcpd.conf > /dev/null then sudo cat >> "/etc/dhcp/dhcpd.conf" << EOF subnet $LAN netmask $NETMASK { range $DHCP_START $DHCP_END; option routers $SRVIP; default-lease-time 600; max-lease-time 7200; option domain-name-servers 8.8.8.8; } EOF fi sudo systemctl restart isc-dhcp-server sleep 1 fi # Установить адрес внутренней сети в соответствии с номером вашего компьютера 192.168.Х.1 echo -e "${GREEN}Setting up netplan..${NC}" sed -z -i 's/'"$LANINT"':\n dhcp4: true/'"$LANINT"':\n addresses: ['"$SRVIP"'\/'"$SRVIPMASK"']/' \ /etc/netplan/$NETPLAN echo -e "${RED}$(cat /etc/netplan/$NETPLAN)${NC}" sudo netplan apply sleep 1 # Настраиваем SSH, меняем порт на $SSH_PORT (2223) # Разрешить доступ к SSH только по ключу. Но, защитить доступ к серверу (после 5 неправильных попыток ввода пароля, ban ip address источника на 1 час) echo -e "${GREEN}Setting up ssh..${NC}" if [[ $(grep -Fxq "Port $SSH_PORT" /etc/ssh/sshd_config) -eq 0 ]] then [[ $(grep -Eiq "^.?Port 22$" /etc/ssh/sshd_config) -ne 0 ]] && \ echo "Port $SSH_PORT" >> /etc/ssh/sshd_config || \ sed -i 's/^.\?Port 22$/Port '"$SSH_PORT"'/' /etc/ssh/sshd_config fi echo -e "${RED}$(cat /etc/ssh/sshd_config | grep -Ei '^.?Port')${NC}" sed -i 's/^.\?PubkeyAuthentication yes$/PubkeyAuthentication yes/' \ /etc/ssh/sshd_config echo -e "${RED}$(cat /etc/ssh/sshd_config | grep -Ei '^.?PubkeyAuthentication')${NC}" #sed -i 's/^PasswordAuthentication yes$/PasswordAuthentication no/' \ # /etc/ssh/sshd_config echo -e "${RED}$(cat /etc/ssh/sshd_config | grep -Ei '^.?PasswordAuthentication')${NC}" sudo systemctl restart ssh echo -e "${GREEN}Setting up fail2ban..${NC}" cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local if ! grep -Fxiq "[sshd]" /etc/fail2ban/jail.local > /dev/null then sudo cat >> "/etc/fail2ban/jail.local" << EOF [sshd] enabled = true maxretry = 5 bantime = 3600 EOF sudo systemctl restart fail2ban fi sudo systemctl enable fail2ban sleep 1 echo -e "${GREEN}Setting up iptables..${NC}" # Чистим правила $IPT -F $IPT -t nat -F # Запретить все входящие, исходящие и транзитные пакеты $IPT -P INPUT DROP $IPT -P FORWARD DROP $IPT -P OUTPUT DROP # Разрешить только ESTABLISHED и RELATED пакеты $IPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # Разрешить доступ в internet для вашей локальной сети echo 1 > /proc/sys/net/ipv4/ip_forward sudo sysctl -p # PS! Можно обозначить -m multiport --dports 80,443 как --dports http,https $IPT -A FORWARD -s $LAN/$SRVIPMASK -o $WANINT -i $LANINT -p tcp -m multiport --dports 80,443 -j ACCEPT $IPT -A FORWARD -d $LAN/$SRVIPMASK -o $LANINT -i $WANINT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT $IPT -A FORWARD -s $LAN/$SRVIPMASK -o $WANINT -i $LANINT -p icmp -j ACCEPT $IPT -A FORWARD -d $LAN/$SRVIPMASK -o $LANINT -i $WANINT -p icmp -m icmp --icmp-type 0 -j ACCEPT $IPT -t nat -A POSTROUTING -o $WANINT -j MASQUERADE # Проверить работу интернет из локальной сети используя windows server 2019 # + # Разрешить доступ к сервису SSH на сервере ubuntu как из локальной сети, так и из внешней, обязательно поменять порт) # Сделать настройку SSH сервиса: # По умолчанию порт сервиса закрыт # Если приходят три icmp пакета размером 93 42 107 соответственно, то порт открывается для подключения на 1 минуту, для адреса (SA) с которого приходили пакеты sudo ipset list KNOCK_ALLOW > /dev/null 2>&1 && \ sudo ipset flush KNOCK_ALLOW || \ sudo ipset create KNOCK_ALLOW hash:net,iface timeout 60 $IPT -I INPUT 1 -p icmp --icmp-type 8 -m length --length 135:135 -m recent --rcheck --seconds 10 --name KNOCK2 --rsource -j SET --add-set KNOCK_ALLOW src,src --exist $IPT -I INPUT 2 -p icmp --icmp-type 8 -m length --length 70:70 -m recent --rcheck --seconds 10 --name KNOCK1 --rsource -m recent --set --name KNOCK2 --rsource $IPT -I INPUT 3 -p icmp --icmp-type 8 -m length --length 121:121 -m recent --set --name KNOCK1 --rsource $IPT -A INPUT -p tcp -m tcp --dport $SSH_PORT -m set --match-set KNOCK_ALLOW src,src -j ACCEPT $IPT -A INPUT -p tcp -m tcp --dport $SSH_PORT -j DROP $IPT -A OUTPUT -p tcp -m tcp --sport $SSH_PORT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT echo / > /proc/net/xt_recent/KNOCK1 echo / > /proc/net/xt_recent/KNOCK2 # Разрешить ping на сервер из локальной сети $IPT -A INPUT -s $LAN/$SRVIPMASK -p icmp -i $LANINT -j ACCEPT $IPT -A OUTPUT -d $LAN/$SRVIPMASK -p icmp -o $LANINT -j ACCEPT # Выполнить проброс RDP порта (3389) через ubuntu server (из внешней сети (сеть школы, адаптер bridge) во внутреннюю сеть (вашу локальную сеть). Входящий порт на router сделать 5556. # https://ipset.netfilter.org/iptables-extensions.man.html # --to-destination [ipaddr[-ipaddr]][:port[-port]] # which can specify a single new destination IP address, an inclusive range of IP addresses. Optionally a port range, if the rule also specifies one of the following protocols: tcp, udp, dccp or sctp. If no port range is specified, then the destination port will never be modified. If no IP address is specified then only the destination port will be modified. In Kernels up to 2.6.10 you can add several --to-destination options. For those kernels, if you specify more than one destination address, either via an address range or multiple --to-destination options, a simple round-robin (one after another in cycle) load balancing takes place between these addresses. Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges anymore. WSRV_IP=$(awk -F. '{print $1"."$2"."$3"."2}' <<< $LAN) # $IPT -t nat -A PREROUTING -i $WANINT -p tcp -m tcp --dport 5556 -j DNAT --to-destination 192.168.77.1-192.168.77.100:3389 $IPT -t nat -A PREROUTING -i $WANINT -p tcp -m tcp --dport 5556 -j DNAT --to-destination $WSRV_IP:3389 $IPT -A FORWARD -d $WSRV_IP/32 -i $WANINT -o $LANINT -p tcp -m tcp --dport 3389 -j ACCEPT # Дополнительно, открываем loopback интерфейс $IPT -A INPUT -i lo -j ACCEPT $IPT -A OUTPUT -o lo -j ACCEPT # Закрыть icmp пакеты для подозрительного источника на 1 час, в случае если от этого источника за минуту пришло более 20 пакетов ICMP sudo ipset list BADGUY > /dev/null 2>&1 && \ sudo ipset flush BADGUY || \ sudo ipset create BADGUY hash:net,iface timeout 3600 $IPT -I INPUT 1 -p icmp -m set --match-set BADGUY src,src -j DROP $IPT -I INPUT 2 -p icmp -m recent --rcheck --seconds 60 --hitcount 20 --name ICMP_CHECK --rsource -j SET --add-set BADGUY src,src --exist $IPT -A INPUT -p icmp --icmp-type 8 -m recent --set --name ICMP_CHECK --rsource -j ACCEPT $IPT -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT echo / > /proc/net/xt_recent/ICMP_CHECK # Сделать автоматическое сохранение правил firewall echo -e "${GREEN}Setting up iptables save & restore..${NC}" SAVE_PATH=$(eval echo "~") echo -e "SAVE_PATH: ${RED}$SAVE_PATH${NC}" sudo iptables-save > $SAVE_PATH/iptables.rules sudo iptables-restore < $SAVE_PATH/iptables.rules sudo touch "$SAVE_PATH/firewall.sh" sudo cat > "$SAVE_PATH/firewall.sh" << EOF #!/bin/bash sudo iptables-restore < $SAVE_PATH/iptables.rules EOF sudo chmod +x "$SAVE_PATH/firewall.sh" if ! $(crontab -l | grep -Fwiq "@reboot bash $SAVE_PATH/firewall.sh") then sudo crontab -l | { cat; echo "@reboot bash $SAVE_PATH/firewall.sh"; } | sudo EDITOR=nano crontab - fi echo -e "${GREEN}Showing information..${NC}" sleep 1 # watch -d iptables -L -v -n ipset list KNOCK_ALLOW | grep -E "Name|Type|Number of entries|Members" ipset list BADGUY | grep -E "Name|Type|Number of entries|Members" iptables -L -v -n