Как сохранить правила iptables

准备开始

在命令行上使用 iptables 需要 root 的权限,因此你必须化身为 root 用户来做下面的事情。

注意: 我们将会停用 iptables 及复位你的防火墙规则,因此假若你依赖你的 Linux 防火墙作为第一道防线,请特别留意这点。

iptables 应该缺省被安装在所有 CentOS 5.x 及 6.x 上。你可以这样来检查 iptables 是否已安装在你的系统上:

$ rpm -q iptables
iptables-1.4.7-5.1.el6_2.x86_64

要知道 iptables 是否正在运作中,我们可以检查 iptables 这个模块是否已被装入,并利用 -L 这个选项来查看活动的规则:

# lsmod | grep ip_tables
ip_tables              29288  1 iptable_filter
x_tables               29192  6 ip6t_REJECT,ip6_tables,ipt_REJECT,xt_state,xt_tcpudp,ip_tables
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

从上面我们可看见一台 CentOS 6 系统的缺省规则。请留意访问 SSH 服务缺省是获允许的。

如果 iptables 并未被执行,你可以这样启用它:

# system-config-securitylevel

Настройка Source NAT: доступ из локальной сети в Интернет

При source NAT для серверов внешней сети, запросы от наших клиентов из внутренней сети будут выглядеть так, как будто с ними общается напрямую сервер шлюз — gw-server01.

В прошлой статье “Базовая настройка файервола Linux с помощью iptables” мы рассмотрели азы использования iptables. В этот раз, работать в iptables будем не только с таблицей filter, но и с таблицей nat. В отличие от таблицы для фильтрации трафика filter, таблица nat содержит следующие chains(цепочки):

  • PREROUTING — в этой цепочке обрабатываются входящие IP пакеты, до их разделения на предназначенные для самого сервера или для передачи другому, т.е. до принятия решения о выборе маршрута для IP пакета;
  • OUTPUT – цепочка предназначена для обработки IP пакетов, которые сгенерированы локально приложением на сервере. Локально сгенерированные IP пакеты не проходят цепочку PREROUTING;
  • POSTROUTING — в этой цепочке обрабатываются все исходящие IP пакеты, уже после принятия решения о маршруте для IP пакета.

Отличаются и действия, выполняемые для IP пакетов, в этой таблице:

  • MASQUERADE и SNAT— производит подмену IP адреса источника для исходящих пакетов. Отличием этих действий является то, что SNAT дает возможность задать конкретный IP адрес нового источника, а в случае MASQUERADE это происходит динамически;
  • DNAT — производит подмену IP адреса назначения для входящих пакетов.

Важно: действие MASQUERADE и SNAT задается только для цепочки POSTROUTING, а действие DNAT только для цепочек PREROUTING или OUTPUT.

На рисунке 2 изображены этапы обработки IP пакета из внутренней сети на шлюзе gw-server01 при SNAT на iptables. IP адрес и порт назначения при этом остаются неизменными.

Рисунок 2

  1. IP пакет поступил на внутренний интерфейс eth1 сервера gw-server01. Так как IP назначения не принадлежит серверу gw-server01, IP пакет переходит к обработке цепочкой FORWARD.
  2. После прохождения цепочки FORWARD, для IP пакета определяется исходящий сетевой интерфейс, с которого он должен быть отправлен, это отмечено желтым цветом
  3. В конце IP пакет проходит цепочку POSTROUTING, в которой происходит подмена IP адреса источника, на IP адрес внешнего интерфейса eth0 сервера gw-server01

Приступим к настройке. Сначала нужно установить параметр ядра, который позволяет передавать пакеты между интерфейсами сервера. Для этого в файл /etc/sysctl.conf добавим переменную:

Чтобы применить изменения, выполним команду

здесь sysctl это команда, которая позволяет управлять параметрами ядра, ключ -p означает, что нужно считать параметры из файла.

Создадим правило в iptables, разрешающее передачу пакетов между внутренним (eth1) и внешним (eth0) интерфейсом:

и разрешим передавать между интерфейсами пакеты, относящиеся к уже установленным соединениям.

Предыдущие два правила имеет смысл создавать, только если для цепочки FORWARD по умолчанию установлена политика DROP:

Включение SNAT:

  • —to-source должен быть адресом на интерфейсе, с которого планируется выпускать во внешнюю сеть IP пакеты;
  • -s 10.2.0.0/24 задано из расчета, что внутренняя сеть 10.2.0.0/24, но это необязательный параметр, если его не указать, ограничений на источник взаимодействия не будет.

Посмотрим получившуюся конфигурацию для таблицы filter и цепочки FORWARD (вывод обрезан):

и конфигурацию для таблицы nat и цепочки POSTROUTING (вывод обрезан):

Для проверки, что наш веб-сервер во внутренней сети получил доступ в Интернет, попробуем подключиться через telnet на адрес 1.1.1.1 (Cloudflare DNS) порт 80:

Вывод команды Connected 1.1.1.1, показывает, что подключение прошло успешно.

引言

CentOS 內置了一個非常強勁的防火牆,統稱為 iptables,但更正確的名稱是 iptables/netfilter。iptables 是一個用戶空間的模塊。作為用戶,你在指令行就是透過它將防火牆規則放進預設的表裡。netfilter 是一個核心模塊,它內置於內核中,進行實際的過濾。iptables 有很多前端圖像介面可以讓用戶新增或定義規則,但它們很多時不及使用指令行般有彈性,而且限制用戶瞭解實際發生的事情。我們將會學習 iptables 的指令行介面。

在我們正式應付 iptables 前,我們必須對它的運作有一個基本的理解。iptables 利用到 IP 位址、協定(tcp、udp、icmp)及連接埠這些概念。我們不需要成為這些方面的專家(因為我們可以找到所需的資訊),但對它們有一般的理解會有幫助。

iptables 將規則放進預設的規則鏈(INPUT、OUTPUT 及 FORWARD),而所有流量(IP 封包)都會被相關的規則鏈檢查,根據當中的規則判斷如何處理每個封包,例如:接納或丟棄它。這些動作稱為目標,而最常見的兩個預設目標就是 DROP 來丟棄封包;或 ACCEPT 來接納封包。

規則鏈

我們可以在過濾表的 3 條預設規則鏈內加入規則,來處理通過這些規則鏈的封包。它們分別是:

  • INPUT — 所有以主機為目的地的封包。
  • OUTPUT — 所有源自主機的封包。
  • FORWARD — 這些封包的目的地或來源地都不是主機,但路經主機(由它選路)。假若你的主機是一個路由器,這條規則鏈將會被應用。

我們將會花費最多時間處理 INPUT 規則鏈,藉以過濾進入我們的機器的封包 —— 亦即是將壞蛋拒諸門外。

規則是以列表的方式被加進每條規則鏈。每個封包會被頭一條規則開始檢查,才至最後一條。假若封包與其中一條規則吻合,相應的動作便會被執行,例如接納(ACCEPT)或丟棄(DROP)封包。一旦有吻合的規則,這個封包便會按照規則來處理,而不再被規則鏈內的其它規則所檢查。假如封包通過所有檢查而不符合任何規則鏈內的任何一條規則,那應這條規則鏈的預設動作將會被執行。這就是所謂的預設政策,可以設定為接納(ACCEPT)或丟棄(DROP)封包。

規則鏈擁有預設政策這個概念帶來兩個基本的可能性,而我們必須考慮它們才能決定如何組織我們的防火牆。

1. 我們可以預設一個政策來丟棄(DROP)所有封包,然後刻意加入規則來接納(ACCEPT)源自被信任的 IP 位址的封包,或者開啟那些提供服務的連接埠,如:bittorrent、FTP 伺服器、網頁伺服器、Samba 檔案伺服器等。

又或者,

2. 我們可以預設一個政策來接納(ACCEPT)所有封包,然後刻意加入規則來攔截(DROP)來自有問題的 IP 位址或系列的封包,也或者阻止封包進出只作私人用途或未提供服務的連接埠。

普遍來說,第一個方法多數用在 INPUT 規則鏈,因為我們會希望控制哪些東西可以存取我們的機器;而第二個方法多數用在 OUTPUT 規則鏈,因為我們多數信賴那些離開(源自)我們機器的封包。

Introduction

In today’s guide let’s walk through how to migrate iptables to nftables from any RHEL 6 or 7 Linux servers to RHEL 8 based operating systems. The feature of migrating iptables to nftables eliminates a lot of pain in rewriting complex iptables rules.

Currently, we are running on RHEL 7, The requirement is to migrate our running production from RHEL 7 to 8. In this case, we need more flexibility during the whole migration process. To make the migration smoother RHEL 8 and variants comes with “iptables-restore-translate” command which helps to migrate the existing iptables rules to nftables.

Before starting with migration, let’s prepare by saving the rules to a file.

If you are looking to start with SELinux, click to read now

Export IPtables to a file

First of all, we need to save all our iptables rules by redirecting to a file in any name and extension. This is simple as we do in our usual daily activities.

Next step to verify.

Verify the Existing Rules

To verify the saved rules just do a cat and go through the rules. Make sure to confirm whether all the rules are saved.

It’s confirmed we have only a few rules as shown below.

# cat iptables_rules.txt 
# Generated by iptables-save v1.4.21 on Tue Aug 27 23:47:24 2019
*filter
:INPUT ACCEPT 
:FORWARD ACCEPT 
:OUTPUT ACCEPT 
-A INPUT -p udp -m udp --dport 636 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 636 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p udp -m udp --dport 389 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 389 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A OUTPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Tue Aug 27 23:47:24 2019
#

Once the rules are saved, copy the file “iptables_rules.txt” to the destination server running on RHEL 8 based operating system.

Convert the Iptables to nftables

On the RHEL 8 based operating system, Start to convert the iptables rules by running translate command by specifying the copied iptables file and redirect the output to save as nft rules.

we have converted our iptables rules to nftables.

Load and Import the rules

Load the rules using -f option by specifying the converted “nft_ruleset.nft” rules file.

Once run with the above command we are done with import the rules into nft.

List and verify the nftables

Finally, list and verify the imported rules.

While listing, We should see as shown below.

# nft list ruleset
table ip filter {
	chain INPUT {
		type filter hook input priority 0; policy accept;
		udp dport ldaps ct state established,new counter packets 0 bytes 0 accept
		tcp dport ldaps ct state established,new counter packets 0 bytes 0 accept
		udp dport ldap ct state established,new counter packets 0 bytes 0 accept
		ct state new tcp dport ssh counter packets 0 bytes 0 accept
		tcp dport ldap ct state established,new counter packets 0 bytes 0 accept
		ct state new tcp dport xmpp-server counter packets 0 bytes 0 accept
		ct state new tcp dport xmpp-client counter packets 0 bytes 0 accept
		ct state new tcp dport https counter packets 0 bytes 0 accept
		ct state new tcp dport http counter packets 0 bytes 0 accept
	}

	chain FORWARD {
		type filter hook forward priority 0; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 0; policy accept;
		ct state new tcp dport ssh counter packets 0 bytes 0 accept
		ct state new tcp dport https counter packets 0 bytes 0 accept
		ct state new tcp dport http counter packets 0 bytes 0 accept
	}
}

That’s it we have successfully migrated our existing iptables rules to nftables without spending time on writing any nftable rules.

Enable Iptables

In my default installation of CentOS 7 I already have the iptables package installed which can be used to run the iptables command, however we also need to install iptables-services in order to have iptables start automatically on system boot.

 ~]# yum install iptables-services -y

We will now check the status of iptables, as shown below after a clean install it will not be currently running and will be set to disabled, that is it will not start automatically on system boot.

 ~]# systemctl status iptables
iptables.service - IPv4 firewall with iptables
   Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

After the installation is complete, we will configure iptables to start automatically on system boot.

 ~]# systemctl enable iptables
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.

Next we will start iptables, activating the firewall.

 ~]# systemctl start iptables

Now if we check the status of iptables, we should see that it is both actively running, and enabled to start on system boot.

 ~]# systemctl status iptables
iptables.service - IPv4 firewall with iptables
   Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
   Active: active (exited) since Tue 2016-12-27 02:54:27 PST; 1min 52s ago
  Process: 44351 ExecStart=/usr/libexec/iptables/iptables.init start (code=exited, status=0/SUCCESS)
 Main PID: 44351 (code=exited, status=0/SUCCESS)

Dec 27 02:54:27 localhost.localdomain systemd: Starting IPv4 firewall with iptables...
Dec 27 02:54:27 localhost.localdomain iptables.init: iptables: Applying firewall rules: 
Dec 27 02:54:27 localhost.localdomain systemd: Started IPv4 firewall with iptables.

You can now configure the iptables firewall as usual by modifying the /etc/sysconfig/iptables file. We can confirm this is the correct file to use by using the rpm -qc command against the iptables-services package that we installed earlier, as this will list all default configuration files associated with the package.

 ~]# rpm -qc iptables-services
/etc/sysconfig/ip6tables
/etc/sysconfig/iptables

Note that you will also need to start and enable ip6tables for IPv6, as iptables only supports IPv4. Likewise IPv6 specific firewall configuration should be set within the /etc/sysconfig/ip6tables file.

Each of these files contains default configuration to allow TCP port 22 in from any source IP address, so you don’t have to worry about locking yourself out of SSH access during the configuration.

If you make any changes to either of these files, be sure to restart iptables to apply the changes.

 ~]# systemctl restart iptables

Adding rules

Firewalls can commonly be configured in one of two ways, either set the default rule to accept and then block any unwanted traffic with specific rules, or by using the rules to define allowed traffic and blocking everything else. The latter is often the recommended approach, as it allows pre-emptively blocking traffic, rather than having to reactively reject connections that should not be attempting to access your cloud server.

To begin using iptables, you should first add the rules for allowed inbound traffic for the services you require. Iptables can track the state of the connection, so use the command below to allow established connections continue.

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

You can check that the rule was added using the same sudo iptables -L as before.

Next, allow traffic to a specific port to enable SSH connections with the following.

sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

The ssh in the command translates to the port number 22, which the protocol uses by default. The same command structure can be used to allow traffic to other ports as well. To enable access to an HTTP web server, use the following command.

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

After adding all the allowed rules you require, change the input policy to drop.

sudo iptables -P INPUT DROP

Ограничение доступа ssh по группам и пользователям домена

На текущий момент подключиться к серверу может любой пользователь домена. Исправим это и разрешим подключаться только пользователям из группы gr_linux_adm. Для этого правим конфиг /etc/sssd/sssd.conf, добавляя туда новые параметры.

# mcedit /etc/sssd/sssd.conf
access_provider = simple
simple_allow_users = user55@xs.local
simple_allow_groups = gr_linux_adm@xs.local

Обращаю внимание, что параметр access_provider у вас уже будет установлен в другое значение. Надо это изменить

Вы можете добавить разрешение как для конкретного пользователя, так и для целых групп. Сохраняйте конфиг и перезапускайте sssd.

# systemctl restart sssd

Теперь подключиться по ssh к серверу сможет только пользователь домена user55 и все члены группы gr_linux_adm.

Для разбора полетов и решения проблем нужно использовать лог файл — /var/log/secure. Вот пример успешного подключения:

Jul 12 18:10:44 xs-centos7-test sshd: pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.1.3.221 user=lin-user
Jul 12 18:10:44 xs-centos7-test sshd: Accepted password for lin-user from 10.1.3.221 port 51063 ssh2
Jul 12 18:10:45 xs-centos7-test sshd: pam_unix(sshd:session): session opened for user lin-user by (uid=0)

А вот кусок лога подключения доменного пользователя, для которого доступ по ssh закрыт.

Jul 12 18:08:28 xs-centos7-test sshd: pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.1.3.221 user=vzap
Jul 12 18:08:28 xs-centos7-test sshd: pam_sss(sshd:account): Access denied for user vzap: 6 (Permission denied)
Jul 12 18:08:28 xs-centos7-test sshd: Failed password for vzap from 10.1.3.221 port 51057 ssh2
Jul 12 18:08:28 xs-centos7-test sshd: fatal: Access denied for user vzap by PAM account configuration 

Здесь видно, что идентификация пользователя прошла корректно, но доступ к серверу запрещен.

引言

CentOS 内置了一个非常强劲的防火墙,统称为 iptables,但更正确的名称是 iptables/netfilter。iptables 是一个用户空间的模块。作为用户,你在命令行就是通过它将防火墙规则放进缺省的表里。netfilter 是一个核心模块,它内置于内核中,进行实际的过滤。iptables 有很多前端图像界面可以让用户新增或定义规则,但它们很多时不及使用命令行般有灵活性,而且限制用户了解实际发生的事情。我们将会学习 iptables 的命令行界面。

在我们正式应付 iptables 前,我们必须对它的运作有一个基本的理解。iptables 利用到 IP 地址、协议(tcp、udp、icmp)及端口这些概念。我们不需要成为这些方面的专家(因为我们可以找到所需的信息),但对它们有一般的理解会有帮助。

iptables 将规则放进缺省的规则链(INPUT、OUTPUT 及 FORWARD),而所有流量(IP 封包)都会被相关的规则链检查,根据当中的规则判断如何处理每个封包,例如:接纳或丢弃它。这些动作称为目标,而最常见的两个缺省目标就是 DROP 来丢弃封包;或 ACCEPT 来接纳封包。

规则链

我们可以在过滤表的 3 条缺省规则链内加入规则,来处理通过这些规则链的封包。它们分别是:

  • INPUT — 所有以主机为目的地的封包。
  • OUTPUT — 所有源自主机的封包。
  • FORWARD — 这些封包的目的地或来源地都不是主机,但路经主机(由它选路)。假若你的主机是一个路由器,这条规则链将会被应用。

我们将会花费最多时间处理 INPUT 规则链,藉以过滤进入我们的机器的封包 —— 亦即是将坏蛋拒诸门外。

规则是以列表的方式被加进每条规则链。每个封包会被头一条规则开始检查,才至最后一条。假若封包与其中一条规则吻合,相应的动作便会被执行,例如接纳(ACCEPT)或丢弃(DROP)封包。一旦有吻合的规则,这个封包便会按照规则来处理,而不再被规则链内的其它规则所检查。假如封包通过所有检查而不符合任何规则链内的任何一条规则,那应这条规则链的缺省动作将会被执行。这就是所谓的缺省政策,可以设置为接纳(ACCEPT)或丢弃(DROP)封包。

规则链拥有缺省政策这个概念带来两个基本的可能性,而我们必须考虑它们才能决定如何组织我们的防火墙。

1. 我们可以缺省一个政策来丢弃(DROP)所有封包,然后刻意加入规则来接纳(ACCEPT)源自被信任的 IP 地址的封包,或者打开那些提供服务的端口,如:bittorrent、FTP 服务器、网页服务器、Samba 文件服务器等。

又或者,

2. 我们可以缺省一个政策来接纳(ACCEPT)所有封包,然后刻意加入规则来拦截(DROP)来自有问题的 IP 地址或系列的封包,也或者阻止封包进出只作私人用途或未提供服务的端口。

普遍来说,第一个方法多数用在 INPUT 规则链,因为我们会希望控制哪些东西可以访问我们的机器;而第二个方法多数用在 OUTPUT 规则链,因为我们多数信赖那些离开(源自)我们机器的封包。

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *