
圖片來源
為什麼使用 Jumpserver 要上靜態路由?
公司現有 VM Network 環境只要是 Web server 的, default gateway 都是設定 Private IP Class B (172.x.0.0/16) 網段,也就是 Load Balance 身上。同時該台 VM 也會有 192.168.x.0/23 /24
的網卡 (192.168.x.254 or 253
在 Forti 身上)
直接上 routing table 會比文字敘述更清楚~
1
2
3
4
5
|
ip r
default via 172.x.x.254 dev eth0 proto static metric 100
172.x.x.0/24 dev eth0 proto kernel scope link src 172.x.x.131 metric 100
192.x.x.0/23 dev eth1 proto kernel scope link src 192.x.x.131 metric 101
|
Jumpserver 只有 192.168.x.0/24
的網卡 (on Forti)
Jumpserver 只有 192.168.x.0/24
的網卡 (on Forti)
Jumpserver 只有 192.168.x.0/24
的網卡 (on Forti)
因為很重要,講三次
情境一: 網路組 NAT Disabled
假設 IP:
Jumpserver 192.168.x.74/24
Target VM 192.168.x.131/24
在沒有以嚴格政策 (Policy) 限制的情況下,Jumpserver 是可以 單向 碰到 Target VM 的。
在 Jumpserver 執行 ping 192.168.x.131
,Target VM 以 tcpdump
是可以看到 src: 192.168.x.74
的 ICMP 封包的。
不過 Jumpserver 卻收不到 echo 回應 原因是 Target VM 會按照既有 routing table 將 echo 封包傳給 default gateway。
情況二: 網路組 NAT Enabled
這個時候當 Forti 收到 src: 192.168.x.74 dst: 192.168.x.131
的封包時會 將 src
替換成 192.168.x.254 (Forti 身上的 Interface)
這個時候 Jumpserver 可以收到來自 Target VM 的 echo 回應沒有問題。但產生一個問題:
- Target VM 收到的封包都是來自
192.168.x.254
的。這樣無法精準控管權限
而靜態路由的解法可以同時達成 (1) 雙方都可以碰到彼此 (2) 精準權限控管
shell script 目標功能
- 編輯
/etc/hosts.deny
,增加 sshd: <Jumpserver_IP>:allow
。(並且統一 sshd: all
格式)
- 增加靜態路由 (1) 即時生效 (2) 永久。 How to Permanently add Static Route in Linux
- 把 Jumpserver SSH public key 加入
/root/.ssh/known_hosts
。
DC1 施作時遇到的問題
/etc/hosts.deny
格式不一致 (有無空格) 導致替換有問題。相關腳本 edit_hosts_allow_script.sh
eth0
eth1
不一致 (某些 VM 192.168.0.0/16
是綁在 eth0
)。這次我想用 Ansible 做判斷式抓取。 (註: 後來還是用 shell script 做判斷)
- (新增功能,之前是用 powershell 跑) 將
DC2_IT_Jumpserver_Demo
的 ssh public key 加到 /root/.ssh/known_hosts
裡面
jumpserver_static_routing_setup.sh
TARGET_IP
設定 Jumpserver 的 IP。
GATEWAY
預設 254
,當該網段的 Gateway 不是在 254
時更改。
ssh_key_name
是 id.rsa.pub
裡面的名稱,用於搜尋是否已存在 VM 裡面。
(20210910 新增) DB_subnet
當遇到 DB 網段時必須手動指定 D2D 網段,否則 Jumpserver 收到的封包封包來源是錯的! 因為 DB 的 default gateway 是 W2D 網段。(以 Jumpserver 使用 D2D 網段訪問目標來說)
謝謝 Rock 被我盧這麼久 XD
註: 目前網卡名稱只支援 eth.*
與 ens.*
。
註: 應該先判斷是否有 172 這張網卡,在判斷是否有 192 這張網卡。如果沒有 172 (例如: DB) 就不用加靜態路由了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#!/bin/bash
export TARGET_IP='192.168.x.74'
export GATEWAY='254'
export ssh_key_name="root@DC2_BD_IT_Jumpserver_Demo"
export DB_subnet=""
## Task 1: edit `/etc/hosts.deny`
sed -i -e 's|^sshd:\ \{0,\}all||g' -e '/^$/d' /etc/hosts.deny
echo "sshd: ${TARGET_IP}:allow" >> /etc/hosts.deny
echo "sshd: all" >> /etc/hosts.deny
## ==========
## Task 2: add static routing (即時 + 永久)
### 先判斷是否有 192.168.x.0/24 這張網卡,若有才執行。 FLAG != '0' 代表沒有
ifconfig | grep '192.168.' > /dev/null
FLAG_eth=$(echo $?)
if [ "$FLAG_eth" == "0" ]; then
#echo '找到 192.168. 網卡!'
## 192.168 網段。例如: 192.168."212".254。 "212" 會是輸出內容
## 有把 DB 有兩張 192.168 的網卡考慮進去 (head -n1 的部分)
export SUBNET=""
export SUBNET=$(ifconfig | grep -e "inet 192.168.${DB_subnet}" | sed -e 's|^ *||g' | cut -d ' ' -f 2 | cut -d '.' -f 3 | head -n1)
## 192.168 網卡名稱。有把 DB 有兩張 192.168 的網卡考慮進去 (head -n1 的部分)
export TARGET_NIC=""
export TARGET_NIC=$(ifconfig | grep -e "inet 192.168.${DB_subnet}" -U1 | cut -d ' ' -f 1 | cut -d ':' -f 1 | grep -oE "(eth.*)||(ens.*)" | head -n1)
## 網段、網卡 均不為空值才會繼續執行
if [ -n "$SUBNET" ] && [ -n "$TARGET_NIC" ]; then
## 即時靜態路由 (若已存在該筆,則不會執行)
FLAG_route=""
route | grep "${TARGET_IP}" &>/dev/null
FLAG_route=$(echo $?)
if [ "$FLAG_route" == "1" ]; then
echo '即時靜態路由執行!'
route add -net ${TARGET_IP} netmask 255.255.255.255 gw 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}
fi
## 永久靜態路由
conf_path="/etc/sysconfig/network-scripts/route-${TARGET_NIC}"
grep "${TARGET_IP}" ${conf_path} &>/dev/null
FLAG_conf=$(echo $?)
if [ "$FLAG_conf" != "0" ]; then
echo '永久靜態路由執行!'
echo "${TARGET_IP} via 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}" >> /etc/sysconfig/network-scripts/route-${TARGET_NIC}
fi
fi
fi
## ==========
## Task 3: Public Key insert. 信任公鑰注入
mkdir -p /root/.ssh/ && touch /root/.ssh/authorized_keys
FLAG_ssh=""
grep ${ssh_key_name} /root/.ssh/authorized_keys &>/dev/null
FLAG_ssh=$(echo $?)
if [ "$FLAG_ssh" != "0" ]; then
echo 'SSH Public Key 執行!'
cat >> /root/.ssh/authorized_keys << EOF
ssh-rsa XXXX root@DC2_BD_IT_Jumpserver_Demo
EOF
fi
|
Ansible Play Book
事前準備
在工作目錄準備:
inventory
jumpserver_static_routing_setup.sh
net-tools-2.0-0.25.20131004git.el7.x86_64.rpm
(Play Book 本人) script_play_book.yml
script_play_book.yml
請自行替換 hosts
為 inventory 內目標 group name
Task 1~2 都是安裝/更新 net-tools
的步驟,在 when
的地方有限定 RHEL/CentOS 7 才安裝。 (net-tools 說明)
由於若已安裝 net-tools v2.0-0.25
會報錯,導致 Task 3 沒有被執行。因此加了一行 ignore_errors: yes
Task 3 用 script
module 執行位於 local (Ansible control node) 的 shell script。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
---
## 使用 Ansible Script module 執行 .sh file
- name: Run a script for setup Jumpserver.
hosts: librenms
tasks:
- name: copy 'net-tools.rpm' to remote VM
copy:
src: net-tools-2.0-0.25.20131004git.el7.x86_64.rpm
dest: /tmp/
when: ansible_os_family == "RedHat" and ansible_facts['distribution_major_version'] == "7"
- name: Install 'net-tools'
shell:
cmd: rpm -Uvh --nosignature /tmp/net-tools-2.0-0.25.20131004git.el7.x86_64.rpm
warn: false
when: ansible_os_family == "RedHat" and ansible_facts['distribution_major_version'] == "7"
ignore_errors: yes
- name: Run the 'jumpserver_static_routing_setup.sh'
script: jumpserver_static_routing_setup.sh
when: ansible_os_family == "RedHat"
|
後記
原本打算完全用 Ansible 完成這個任務,不過還是跟 shell script 比較熟一點 XD 只好混搭 Ansible 來使用。
2021/12/23 異動
DC2_BD_IT_Jumpserver_Demo
IP 192.168.x.74 => 192.168.x.240
Change_IP_jumpserver_static_routing_setup.sh
- 新增
OLD_TARGET_IP
。
- shell script 會針對舊的 IP (
192.168.110.74
) 從相關 config file 移除。
- SSH public key 不會因為更改 IP 失效,因此移除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#!/bin/bash
export TARGET_IP='192.168.x.240'
export OLD_TARGET_IP='192.168.x.74'
export GATEWAY='254'
#export ssh_key_name="root@DC2_BD_IT_Jumpserver_Demo"
export DB_subnet=""
## Task 1: edit `/etc/hosts.deny`
sed -i -e "s|^sshd:\ \{0,\}${OLD_TARGET_IP}:allow||g" /etc/hosts.deny
sed -i -e 's|^sshd:\ \{0,\}all||g' -e '/^$/d' /etc/hosts.deny
echo "sshd: ${TARGET_IP}:allow" >> /etc/hosts.deny
echo "sshd: all" >> /etc/hosts.deny
## ==========
## Task 2: add static routing (即時 + 永久)
### 先判斷是否有 192.168.x.0/24 這張網卡,若有才執行。 FLAG != '0' 代表沒有
ifconfig | grep '192.168.' > /dev/null
FLAG_eth=$(echo $?)
if [ "$FLAG_eth" == "0" ]; then
#echo '找到 192.168. 網卡!'
## 192.168 網段。例如: 192.168."212".254。 "212" 會是輸出內容
## 有把 DB 有兩張 192.168 的網卡考慮進去 (head -n1 的部分)
export SUBNET=""
export SUBNET=$(ifconfig | grep -e "inet 192.168.${DB_subnet}" | sed -e 's|^ *||g' | cut -d ' ' -f 2 | cut -d '.' -f 3 | head -n1)
## 192.168 網卡名稱。有把 DB 有兩張 192.168 的網卡考慮進去 (head -n1 的部分)
export TARGET_NIC=""
export TARGET_NIC=$(ifconfig | grep -e "inet 192.168.${DB_subnet}" -U1 | cut -d ' ' -f 1 | cut -d ':' -f 1 | grep -oE "(eth.*)||(ens.*)" | head -n1)
## 網段、網卡 均不為空值才會繼續執行
if [ -n "$SUBNET" ] && [ -n "$TARGET_NIC" ]; then
## 即時靜態路由 (若已存在該筆,則不會執行)
FLAG_route=""
route | grep "${TARGET_IP}" &>/dev/null
FLAG_route=$(echo $?)
if [ "$FLAG_route" == "1" ]; then
echo '即時靜態路由執行!'
route add -net ${TARGET_IP} netmask 255.255.255.255 gw 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}
route del -net ${OLD_TARGET_IP} netmask 255.255.255.255 gw 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}
fi
## 永久靜態路由
conf_path="/etc/sysconfig/network-scripts/route-${TARGET_NIC}"
grep "${TARGET_IP}" ${conf_path} &>/dev/null
FLAG_conf=$(echo $?)
if [ "$FLAG_conf" != "0" ]; then
echo '永久靜態路由執行!'
echo "${TARGET_IP} via 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}" >> /etc/sysconfig/network-scripts/route-${TARGET_NIC}
sed -i -e "/^${OLD_TARGET_IP} via 192.168.${SUBNET}.${GATEWAY} dev ${TARGET_NIC}$/d" /etc/sysconfig/network-scripts/route-${TARGET_NIC}
fi
fi
fi
## ==========
|
Change_IP_script_play_book.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
---
## 使用 Ansible Script module 執行 .sh file
## For Change IP ONLY !!
- name: Run a script for setup Jumpserver.
hosts: librenms
tasks:
- name: Run the 'Change_IP_jumpserver_static_routing_setup.sh'
script: Change_IP_jumpserver_static_routing_setup.sh
when: ansible_os_family == "RedHat"
|
1
|
sudo ansible-playbook -i inventory_Production_85_DB Change_IP_script_play_book.yml
|
Author
LastMod
2022-09-08
(acfa348)