[20020226]iptables PREROUTING POSTROUTING 應用測試.txt

lfree發表於2020-02-27

[20020226]iptables PREROUTING POSTROUTING 應用測試.txt

--//晚上看連結,靈光一線,自己什麼沒有想到
--//利用iptables prerouting可以實現埠重定向以及IP的重定向,測試看看。

--//比如我們生產環境,經常A訪問B,B訪問C,而A不能直接訪問C,我以前都是使用SSH tunnnel實現這個功能A訪問C。
--//這樣帶來的限制是僅僅我一臺電腦能訪問。如果實現多個A訪問C呢?

1.測試環境:
client : 192.168.98.6
server : 192.168.100.78
dg:      192.168.100.40
--//注:測試一定小心小心再小心,不然可能自己都被擋在防火牆外面。不能使用生產系統的伺服器做這樣的測試,切記!!

2.埠重定向。
--//在服務端192.168.100.78執行:
# iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-ports 1521
--//注:連結的例子使用ssh的22埠,我測試害怕出現意外,導致我無法連線伺服器,故而選擇別的埠測試。
--//另外預設規則全部設定為ACCEPT.

--//client 發出:
192.168.98.6:XXX --> 192.168.100.78:2222  重定向到 192.168.100.78:1521
--//service 發出的回包:
192.168.100.78:1521 重定向到 192.168.100.78:2222 --> 192.168.98.6:XXX

--//在客戶端192.168.98.6登入看看:
R:\> echo @ver1 | sqlplus -s -l scott/book@192.168.100.78:2222/book:DEDICATED
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

--//OK,透過。這樣在生產實踐中沒有什麼意思。
--//除非比如原來配置的連線埠是2222。而現在的伺服器是埠1521,底下應用不好大量改動,暫時為之。
--//注:這個語法我還第一次見到.指REDIRECT.

--//tcpdump
# tcpdump -nnn -i eth0  host 192.168.98.6  and not port 514 and not port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
09:10:04.288211 IP 192.168.98.6.55280 > 192.168.100.78.2222: S 258337481:258337481(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
09:10:04.288402 IP 192.168.100.78.2222 > 192.168.98.6.55280: S 2476896751:2476896751(0) ack 258337482 win 14600 <mss 1460,nop,nop,sackOK,nop,wscale 7>
09:10:04.288653 IP 192.168.98.6.55280 > 192.168.100.78.2222: . ack 1 win 16425
09:10:04.288936 IP 192.168.98.6.55280 > 192.168.100.78.2222: P 1:297(296) ack 1 win 16425
09:10:04.288964 IP 192.168.100.78.2222 > 192.168.98.6.55280: . ack 297 win 123
09:10:04.312406 IP 192.168.100.78.2222 > 192.168.98.6.55280: P 1:9(8) ack 297 win 123
09:10:04.313026 IP 192.168.98.6.55280 > 192.168.100.78.2222: P 297:593(296) ack 9 win 16423
09:10:04.313140 IP 192.168.100.78.2222 > 192.168.98.6.55280: P 9:41(32) ack 593 win 131
--//看不到對1521埠的訪問。

R:\> echo @ver1 | sqlplus -s -l scott/book@192.168.100.78:1521/book:DEDICATED
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

--//而且直接訪問1521,一樣ok。

3.重定向IP:
--//在服務端192.168.100.78執行:
--//首先清除前面測試的設定:
# iptables -F -t nat
# iptables -L -n -v  --line-numbers
Chain INPUT (policy ACCEPT 2986K packets, 562M bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 399K packets, 59M bytes)
num   pkts bytes target     prot opt in     out     source               destination
--//注:少寫了-t nat,不過前面的命令已經清除了iptables的配置。
--//在服務端192.168.100.78上先關閉監聽以及資料庫(步驟略)再執行如下:
$ lsnrctl stop
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 26-FEB-2020 09:07:38
Copyright (c) 1991, 2013, Oracle.  All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1521)))
The command completed successfully

# iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 1521 -j DNAT --to-destination 192.168.100.40:1521

R:\>echo @ver1 | sqlplus -s -l scott/book@192.168.100.78:1521/bookdg:DEDICATED
^C
--//掛起!!思考..........困混....
--//遇到這種問題腦子想著網路資料包如何傳輸就自動有答案了,輔助使用tpcdump工具診斷,當然也需要靜下心來思考..。

--//client 192.168.98.6 發出:
192.168.98.6:XXXX --> 192.168.100.78:1521 .
--//到服務端 192.168.100.78 做DNAT。
192.168.98.6:XXXX -->  192.168.100.40:1521

--//tcpdump觀察結果如下:(在192.168.100.78觀察)
# tcpdump -nnn -i eth0 port 1521 or host 192.168.100.40  and not port 514
09:31:54.082137 IP 192.168.98.6.53656 > 192.168.100.78.1521: S 3217747547:3217747547(0) win 8192 <mss 1460,nop,nop,sackOK>
09:31:54.082166 IP 192.168.98.6.53656 > 192.168.100.40.1521: S 3217747547:3217747547(0) win 8192 <mss 1460,nop,nop,sackOK>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--//說明已經發現了DNAT轉換。

--//tcpdump觀察結果如下:(在192.168.100.40觀察)
# tcpdump -i eth0 -nnn host 192.168.100.78 or port 1521 and not port 514
09:32:06.496861 IP 192.168.100.40.1521 > 192.168.98.6.53656: S 28957216:28957216(0) ack 3217747548 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
09:32:30.693197 IP 192.168.100.40.1521 > 192.168.98.6.53656: S 28957216:28957216(0) ack 3217747548 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
09:33:18.885867 IP 192.168.100.40.1521 > 192.168.98.6.53656: S 28957216:28957216(0) ack 3217747548 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
--//噢,這裡就有問題了。因為這樣就沒有經過192.168.100.78了返回。
--//也就是必須在192.168.98.6:XXXX-->192.168.100.40:1521包出去前修改源地址192.168.98.6為192.168.100.78.
--//變成192.168.100.78.6:XXXX-->192.168.100.40:1521,這樣才可能在192.168.100.40出現.
--// 192.168.100.40.1521 > 192.168.100.78.53656.
--//增加iptables規則如下:

# iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 1521 -j DNAT --to-destination 192.168.100.40:1521
# iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp --dport 1521 -j SNAT --to-source 192.168.100.78
or
--//# iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.100.40 --dport 1521 -j SNAT --to-source 192.168.100.78
# iptables -L -n -v -t nat --line-numbers
Chain PREROUTING (policy ACCEPT 54020 packets, 5093K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       60  3120 DNAT       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:1521 to:192.168.100.40:1521

Chain INPUT (policy ACCEPT 3925 packets, 461K bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 554 packets, 33347 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 561 packets, 33703 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       54  2808 SNAT       tcp  --  *      eth0    0.0.0.0/0            0.0.0.0/0           tcp dpt:1521 to:192.168.100.78

R:\>echo @ver1 | sqlplus -s -l scott/book@192.168.100.78:1521/bookdg:DEDICATED
ERROR:
ORA-28032: Your password has expired and the database is set to read-only
SP2-0751: Unable to connect to Oracle.  Exiting SQL*Plus
--//實際上已經登陸成功,我的dg很久不同步了,口令已經expired。換一個使用者看看。

R:\>echo @ver1 |sqlplus -s -l sys/oracle@192.168.100.78:1521/bookdg:DEDICATED as sysdba
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
--//OK.

D:\notes> sqlplus  sys/oracle@192.168.100.78:1521/bookdg:DEDICATED as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Wed Feb 26 09:56:44 2020
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SYS@192.168.100.78:1521/bookdg:DEDICATED>
--//注意看前面的SQL的提示。

R:\>sqlplus -s -l sys/oracle@192.168.100.78:1521/bookdg:DEDICATED as sysdba
select sysdate from dual ;
SYSDATE
------------
2020-02-26 0

select sysdate from dual ;
SYSDATE
-------------------
2020-02-26 09:43:11
--//^_^,12c sqlplus的bug,第一次執行顯示日期不對,第2次ok.
--//看連結:http://blog.itpub.net/267265/viewspace-2561490/=>[20190116]詭異的問題2.txt
--//我不知道這個算不算所謂的資料庫"劫持",不會有人在主庫破環的情況下,採用這樣方式切換dg當正式庫使用吧。

4.繼續測試:
--//在192.168.100.78上啟動監聽以及資料庫(略)。
D:\notes>sqlplus -s -l scott/book@192.168.100.78:1521/book
ERROR:
ORA-28032: Your password has expired and the database is set to read-only
SP2-0751: Unable to connect to Oracle.  Exiting SQL*Plus
--//視乎連線上dg,但是服務名不對啊。噢。我dg上服務名沒修改。

SYS@bookdg> show parameter name
NAME                   TYPE    VALUE
---------------------- ------- ------------------------------------
cell_offloadgroup_name string
db_file_name_convert   string  /mnt/ramdisk/book, /mnt/ramdisk/book
db_name                string  BOOK
db_unique_name         string  bookdg
global_names           boolean FALSE
instance_name          string  bookdg
lock_name_space        string
log_file_name_convert  string  /mnt/ramdisk/book, /mnt/ramdisk/book
processor_group_name   string
service_names          string  book
--//注意service_names=book.也就是使用service_names=book也能臉上dg.

D:\notes>sqlplus -s -l scott/book@192.168.100.78:1521/book1
ERROR:
ORA-12514: TNS:listener does not currently know of service requested in connect
descriptor
SP2-0751: Unable to connect to Oracle.  Exiting SQL*Plus

D:\> sqlplus  sys/oracle@192.168.100.78:1521/book:DEDICATED as sysdba
SYS@192.168.100.78:1521/book:DEDICATED> select DATABASE_ROLE from v$database ;
DATABASE_ROLE
----------------
PHYSICAL STANDBY

D:\> sqlplus  sys/oracle@192.168.100.78:1521/bookdg:DEDICATED as sysdba
SYS@192.168.100.78:1521/bookdg:DEDICATED> select DATABASE_ROLE from v$database ;
DATABASE_ROLE
----------------
PHYSICAL STANDBY
--//說明連線的是dg庫,ip=192.168.100.40

SYS@192.168.100.78:1521/bookdg:DEDICATED> SELECT NVL (SYS_CONTEXT ('userenv', 'ip_address'), '127.0.0.1') c20 from dual ;
C20
--------------------
192.168.100.78
--//你可以發現查詢獲得IP是192.168.100.78,而不是我的客戶端IP=192.168.98.6.
--//也就是即使我開啟服務端1521埠,因為iptable的規則在PREROUTING鏈中,首先起作用,根本不會訪問192.168.100.78的資料庫.

iptables -t nat -F
iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp --dport 1521 -j DNAT --to-destination 192.168.100.40:1521
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp --dport 1521 -j SNAT --to-source 192.168.100.78
--//實現所謂的資料庫"劫持".

5.繼續測試:
--//假設我現在想2個資料庫都要訪問,如何實現呢?重新定義一個新埠15210.
iptables -t nat -F
iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp --dport 15210 -j DNAT --to-destination 192.168.100.40:1521
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp --dport 15210 -j SNAT --to-source 192.168.100.78

# iptables -L -n -v -t nat --line-numbers
Chain PREROUTING (policy ACCEPT 57507 packets, 5415K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DNAT       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:15210 to:192.168.100.40:1521

Chain INPUT (policy ACCEPT 4118 packets, 484K bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 617 packets, 37127 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 624 packets, 37483 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 SNAT       tcp  --  *      eth0    0.0.0.0/0            0.0.0.0/0           tcp dpt:15210 to:192.168.100.78


D:\notes>sqlplus -s -l   sys/oracle@192.168.100.78:15210/bookdg:DEDICATED as sysdba
^C
--//再次掛起,有點得意忘形了^_^。如果在dg 192.168.100.40使用tcpdump看:
# tcpdump -i eth0 -nnn host 192.168.100.78 or port 1521 and not port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
11:04:33.615191 IP 192.168.98.6.58758 > 192.168.100.40.1521: S 3948887925:3948887925(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
11:04:33.615214 IP 192.168.100.40.1521 > 192.168.98.6.58758: S 1596256405:1596256405(0) ack 3948887926 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
11:04:34.509034 IP 192.168.100.40.1521 > 192.168.98.6.58758: S 1596256405:1596256405(0) ack 3948887926 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
--//注意看還是不行,實際上上面的規則SNAT 的dport埠不是15210,而是1521才對。
--//以下是192.168.100.78看到的情況,dnat已經起作用。
# tcpdump -nnn -i eth0 port 15210 or host 192.168.100.40  and not port 514
11:05:04.944946 IP 192.168.98.6.58792 > 192.168.100.78.15210: S 3205587175:3205587175(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
11:05:04.944980 IP 192.168.98.6.58792 > 192.168.100.40.1521: S 3205587175:3205587175(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>

--//修改iptables如下:
iptables -t nat -F
iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp --dport 15210 -j DNAT --to-destination 192.168.100.40:1521
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp --dport 1521 -j SNAT --to-source 192.168.100.78

D:\notes>echo select sysdate,DATABASE_ROLE from v$database ; | sqlplus -s -l  sys/oracle@192.168.100.78:15210/bookdg:DEDICATED as sysdba
SYSDATE      DATABASE_ROLE
------------ ----------------
2020-02-26 1 PHYSICAL STANDBY

D:\notes>echo select sysdate,DATABASE_ROLE from v$database ; | sqlplus -s -l  sys/oracle@192.168.100.78:1521/book:DEDICATED as sysdba
SYSDATE      DATABASE_ROLE
------------ ----------------
2020-02-26 1 PRIMARY
--//OK,這樣就實現透過埠15210訪問192.168.100.40.

總結:
--//好久不搞網路了,有一些生疏。不過最後還是完成了測試,題目應該修改為
--//iptables PREROUTING POSTROUTING應用測試.txt,準確將上面寫的規則有點問題,應該寫成如下以適應不同埠的情況,便於加入多個
--//主機:
iptables -t nat -F
iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp -d 192.168.100.78 --dport 15210 -j DNAT --to-destination 192.168.100.40:1521
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.100.40 --dport 1521  -j SNAT --to-source 192.168.100.78

--//補充這種情況下tcpdump的觀察結果:
--//tcpdump觀察結果如下:(在192.168.100.78觀察)
# tcpdump -nnn -i eth0 port 15210 or host 192.168.100.40  and not port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
09:05:50.848753 IP 192.168.98.6.55044 > 192.168.100.78.15210: S 3035628563:3035628563(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
09:05:50.848981 IP 192.168.100.78.55044 > 192.168.100.40.1521: S 3035628563:3035628563(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SNAT 和 DNAT 都起作用。
09:05:50.848848 IP 192.168.100.40.1521 > 192.168.100.78.55044: S 3715000810:3715000810(0) ack 3035628564 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
09:05:50.848880 IP 192.168.100.78.15210 > 192.168.98.6.55044: S 3715000810:3715000810(0) ack 3035628564 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>

--//tcpdump觀察結果如下:(在192.168.100.40觀察)
# tcpdump -i eth0 -nnn host 192.168.100.78 or port 1521 and not port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
09:05:50.854782 IP 192.168.100.78.55044 > 192.168.100.40.1521: S 3035628563:3035628563(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
09:05:50.854901 IP 192.168.100.40.1521 > 192.168.100.78.55044: S 3715000810:3715000810(0) ack 3035628564 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
09:05:50.855345 IP 192.168.100.78.55044 > 192.168.100.40.1521: . ack 1 win 16425
09:05:50.864963 IP 192.168.100.78.55044 > 192.168.100.40.1521: P 1:300(299) ack 1 win 16425
09:05:50.864981 IP 192.168.100.40.1521 > 192.168.100.78.55044: . ack 300 win 54
09:05:50.906358 IP 192.168.100.40.1521 > 192.168.100.78.55044: P 1:9(8) ack 300 win 54

--//實際上還可以做的更靈活,比如使用不同的dport埠對映不同的伺服器.明天繼續測試。

iptables -t nat -F
iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp -d 192.168.100.78 --dport 10040 -j DNAT --to-destination 192.168.100.40:1521
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.100.40 --dport 1521 -j SNAT --to-source 192.168.100.78

--//有點長,明天另外寫一篇blog。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2677498/,如需轉載,請註明出處,否則將追究法律責任。

相關文章