IPv4 ์ฃผ์๊ฐ ๊ณ ๊ฐ๋จ์ ๋ฐ๋ผ ๋ง์ ํต์ ์ฌ์
์๋ ์ฃผ์ ๋ณํ์ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ์๊ฒ ๋คํธ์ํฌ ์ก์ธ์ค๋ฅผ ์ ๊ณตํด์ผ ํ๋ ํ์์ฑ์ ์ง๋ฉดํ๊ฒ ๋์์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ์์ฉ ์๋ฒ์์ ์บ๋ฆฌ์ด๊ธ NAT ์ฑ๋ฅ์ ์ป์ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช
ํฉ๋๋ค.
์ญ์ฌ์ ๋นํธ
IPv4 ์ฃผ์ ๊ณต๊ฐ ๊ณ ๊ฐ์ด๋ผ๋ ์ฃผ์ ๋ ๋ ์ด์ ์๋ก์ด ๊ฒ์ด ์๋๋๋ค. ์ด๋ค ์์ ์์ RIPE์ ๋๊ธฐ์ ๋ช ๋จ์ด ๋ํ๋ ๋ค์ ์ฃผ์ ๋ธ๋ก์ด ๊ฑฐ๋๋๊ณ ์ด๋ฅผ ์๋ํ๋ ๊ฑฐ๋๊ฐ ์ฒด๊ฒฐ๋๋ ๊ตํ์ด ๋ํ๋ฌ์ต๋๋ค. ์ ์ฐจ์ ์ผ๋ก ํต์ ์ฌ์ ์๋ ์ฃผ์ ๋ฐ ํฌํธ ๋ณํ์ ์ฌ์ฉํ์ฌ ์ธํฐ๋ท ์ก์ธ์ค ์๋น์ค๋ฅผ ์ ๊ณตํ๊ธฐ ์์ํ์ต๋๋ค. ์ผ๋ถ๋ ๊ฐ ๊ฐ์ ์์๊ฒ "ํ์ดํธ" ์ฃผ์๋ฅผ ๋ฐ๊ธํ ๋งํผ ์ถฉ๋ถํ ์ฃผ์๋ฅผ ํ๋ณดํ์ง ๋ชปํ ๋ฐ๋ฉด, ๋ค๋ฅธ ์ผ๋ถ๋ 104์ฐจ ์์ฅ์์ ์ฃผ์ ๊ตฌ๋งค๋ฅผ ๊ฑฐ๋ถํ์ฌ ๋น์ฉ์ ์ ์ฝํ๊ธฐ ์์ํ์ต๋๋ค. ๋คํธ์ํฌ ์ฅ๋น ์ ์กฐ์ ์ฒด๊ฐ ์ด ์์ด๋์ด๋ฅผ ์ง์งํ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์ถ๊ฐ ํ์ฅ ๋ชจ๋์ด๋ ๋ผ์ด์ผ์ค๊ฐ ํ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด Juniper์ MX ๋ผ์ฐํฐ ์ ํ๊ตฐ(์ต์ MX204 ๋ฐ MX1 ์ ์ธ)์์ NAPT๋ ๋ณ๋์ MS-MIC ์๋น์ค ์นด๋์์ ์ํ๋ ์ ์์ผ๋ฉฐ Cisco ASR9k์๋ CGN ๋ผ์ด์ผ์ค๊ฐ ํ์ํ๊ณ Cisco ASR9k์๋ ๋ณ๋์ A100K-ISM-9 ๋ชจ๋์ด ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ AXNUMXK-CGN ๋ผ์ด์ผ์ค -LIC๋ฅผ ๊ทธ์๊ฒ ๋ถ์ฌํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฆ๊ฑฐ์์ ๋๋ฆฌ๋ ค๋ฉด ๋ง์ ๋น์ฉ์ด ๋ญ๋๋ค.
IPTables
NAT๋ฅผ ์ํํ๋ ์์ ์๋ ํน์ํ ์ปดํจํ ๋ฆฌ์์ค๊ฐ ํ์ํ์ง ์์ผ๋ฉฐ, ์๋ฅผ ๋ค์ด ํ ๋ผ์ฐํฐ์ ์ค์น๋ ๋ฒ์ฉ ํ๋ก์ธ์๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค. ํต์ ์ฌ์ ์ ๊ท๋ชจ์์ ์ด ๋ฌธ์ ๋ FreeBSD(ipfw/pf) ๋๋ GNU/Linux(iptables)๋ฅผ ์คํํ๋ ์์ฉ ์๋ฒ๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ FreeBSD๋ฅผ ๊ณ ๋ คํ์ง ์์ ๊ฒ์ ๋๋ค. ์๋ํ๋ฉด... ๋๋ ๊ฝค ์ค๋ ์ ์ ์ด OS๋ฅผ ์ฌ์ฉํ์ง ์์๊ธฐ ๋๋ฌธ์ GNU/Linux๋ฅผ ๊ณ์ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
์ฃผ์ ๋ณํ์ ํ์ฑํํ๋ ๊ฒ์ ์ ํ ์ด๋ ต์ง ์์ต๋๋ค. ๋จผ์ nat ํ ์ด๋ธ์ iptables์ ๊ท์น์ ๋ฑ๋กํด์ผ ํฉ๋๋ค.
iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to <pool_start_addr>-<pool_end_addr> --persistent
์ด์ ์ฒด์ ๋ ๋ชจ๋ ํ์ฑ ์ฐ๊ฒฐ์ ๋ชจ๋ํฐ๋งํ๊ณ ํ์ํ ๋ณํ์ ์ํํ๋ nf_conntrack ๋ชจ๋์ ๋ก๋ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ช ๊ฐ์ง ๋ฏธ๋ฌํจ์ด ์์ต๋๋ค. ์ฒซ์งธ, ํต์ ์ฌ์ ์ ๊ท๋ชจ์ NAT์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ๋ฉด ๋ณํ ํ ์ด๋ธ์ ํฌ๊ธฐ๊ฐ ์น๋ช ์ ์ธ ๊ฐ์ผ๋ก ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ๊ธฐ ๋๋ฌธ์ ์๊ฐ ์ด๊ณผ๋ฅผ ์กฐ์ ํด์ผ ํฉ๋๋ค. ๋ค์์ ๋ด ์๋ฒ์์ ์ฌ์ฉํ ์ค์ ์ ์์ ๋๋ค.
net.ipv4.ip_forward = 1
net.ipv4.ip_local_port_range = 8192 65535
net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_checksum=0
๋์งธ, ๋ณํํ์ ๊ธฐ๋ณธ ํฌ๊ธฐ๋ ํต์ ์ฌ์ ์์ ์กฐ๊ฑด์์ ์๋ํ๋๋ก ์ค๊ณ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋๋ ค์ผ ํฉ๋๋ค.
net.netfilter.nf_conntrack_max = 3145728
๋ํ ๋ชจ๋ ๋ธ๋ก๋์บ์คํธ๋ฅผ ์ ์ฅํ๋ ํด์ ํ ์ด๋ธ์ ๋ฒํท ์๋ฅผ ๋๋ ค์ผ ํฉ๋๋ค(์ด๊ฒ์ nf_conntrack ๋ชจ๋์ ์ต์ ์ ๋๋ค).
options nf_conntrack hashsize=1572864
์ด๋ฌํ ๊ฐ๋จํ ์กฐ์ ํ์๋ ๋ง์ ์์ ํด๋ผ์ด์ธํธ ์ฃผ์๋ฅผ ์ธ๋ถ ์ฃผ์ ํ๋ก ๋ณํํ ์ ์๋ ์๋ฒฝํ๊ฒ ์๋ํ๋ ๋์์ธ์ด ์ป์ด์ง๋๋ค. ๊ทธ๋ฌ๋ ์ด ์๋ฃจ์ ์ ์ฑ๋ฅ์ ์์ง ๋ง์ด ๋ถ์กฑํฉ๋๋ค. NAT์ GNU/Linux๋ฅผ ์ฌ์ฉํ๋ ค๋ ์ฒซ ๋ฒ์งธ ์๋(2013๋ ๊ฒฝ)์์ ์๋ฒ(Xeon E7-0.8v5)๋น 1650Mpps์์ ์ฝ 2Gbit/s์ ์ฑ๋ฅ์ ์ป์ ์ ์์์ต๋๋ค. ๊ทธ ์ดํ๋ก GNU/Linux ์ปค๋ ๋คํธ์ํฌ ์คํ์์ ๋ค์ํ ์ต์ ํ๊ฐ ์ด๋ฃจ์ด์ก์ผ๋ฉฐ ๋์ผํ ํ๋์จ์ด์ ์๋ ํ ์๋ฒ์ ์ฑ๋ฅ์ 18-19 Mpps์์ ๊ฑฐ์ 1.8-1.9 Gbit/s๋ก ์ฆ๊ฐํ์ต๋๋ค(์ด๋ ์ต๋๊ฐ์ ๋๋ค). , ๊ทธ๋ฌ๋ ํ๋์ ์๋ฒ์์ ์ฒ๋ฆฌํ๋ ํธ๋ํฝ ์์ ๋ํ ์์๋ ํจ์ฌ ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ค์ํ ์๋ฒ์ ๋ก๋ ๊ท ํ์ ์กฐ์ ํ๋ ์ฒด๊ณ๊ฐ ๊ฐ๋ฐ๋์์ง๋ง ์ด๋ก ์ธํด ์ ๊ณต๋๋ ์๋น์ค ํ์ง์ ์ค์ , ์ ์ง ๋ฐ ์ ์งํ๋ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํ์ต๋๋ค.
NFTable
์์ฆ ์ํํธ์จ์ด "์ด๋ ๊ฐ๋ฐฉ"์ ์ ํ ์ถ์ธ๋ DPDK ๋ฐ XDP๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ์ด ์ฃผ์ ์ ๊ดํด ๋ง์ ๊ธฐ์ฌ๊ฐ ์์ฑ๋์๊ณ ๋ค์ํ ์ฐ์ค์ด ์ด๋ฃจ์ด์ก์ผ๋ฉฐ ์์ฉ ์ ํ์ด ๋ฑ์ฅํ๊ณ ์์ต๋๋ค(์: VasExperts์ SKAT). ๊ทธ๋ฌ๋ ํต์ ์ฌ์
์์ ์ ํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฆฌ์์ค๋ฅผ ๊ณ ๋ คํ ๋ ์ด๋ฌํ ํ๋ ์์ํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฒด์ ์ผ๋ก "์ ํ"์ ๋ง๋๋ ๊ฒ์ ์๋นํ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ์์ผ๋ก ์ด๋ฌํ ์๋ฃจ์
์ ์ด์ํ๋ ๊ฒ์ ํจ์ฌ ๋ ์ด๋ ค์ธ ๊ฒ์ด๋ฉฐ, ํนํ ์ง๋จ ๋๊ตฌ๊ฐ ๊ฐ๋ฐ๋์ด์ผ ํ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด DPDK๊ฐ ํฌํจ๋ ํ์ค tcpdump๋ ์ด์ ๊ฐ์ด ์๋ํ์ง ์์ผ๋ฉฐ XDP๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ์ผ๋ก ๋ค์ ์ ์ก๋ ํจํท์ "์ธ์"ํ์ง ์์ต๋๋ค. ํจํท ์ ๋ฌ์ ์ฌ์ฉ์ ๊ณต๊ฐ์ผ๋ก ์ถ๋ ฅํ๋ ์๋ก์ด ๊ธฐ์ ์ ๋ํ ๋ชจ๋ ์ด์ผ๊ธฐ ์์์ ๊ทธ๋ค์ ๋์ ๋์ง ์์์ต๋๋ค.
์ฃผ์ ์์ด๋์ด๋ ๋ผ์ฐํฐ๊ฐ ํ๋ฆ์ ์๋ฐฉํฅ์ผ๋ก ํ ์ธ์ ์ ํจํท์ ์ ๋ฌํ ๊ฒฝ์ฐ(TCP ์ธ์ ์ด ESTABLISHED ์ํ๋ก ์ ํ๋จ) ๋ชจ๋ ๋ฐฉํ๋ฒฝ ๊ท์น์ ํตํด ์ด ์ธ์ ์ ํ์ ํจํท์ ์ ๋ฌํ ํ์๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ๋ชจ๋ ๊ฒ์ฌ๋ ํจํท์ด ๋ผ์ฐํ ์ผ๋ก ๋ ์ ์ก๋๋ฉด์ ์ข ๋ฃ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก ๊ฒฝ๋ก๋ฅผ ์ ํํ ํ์๊ฐ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด ์ธ์ ๋ด์์ ์ด๋ค ์ธํฐํ์ด์ค์ ์ด๋ค ํธ์คํธ๋ก ํจํท์ ๋ณด๋ด์ผ ํ๋์ง ์ด๋ฏธ ์๊ณ ์์ต๋๋ค. ๋จ์ ๊ฒ์ ์ด ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ํจํท ์ฒ๋ฆฌ ์ด๊ธฐ ๋จ๊ณ์์ ๋ผ์ฐํ ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. NAT ์ํ ์ nf_conntrack ๋ชจ๋์์ ๋ณํ๋ ์ฃผ์ ๋ฐ ํฌํธ ๋ณ๊ฒฝ ์ ๋ณด๋ฅผ ์ถ๊ฐ๋ก ์ ์ฅํด์ผ ํฉ๋๋ค. ์, ๋ฌผ๋ก ์ด ๊ฒฝ์ฐ iptables์ ๋ค์ํ ์ ์ฑ ๊ณผ ๊ธฐํ ์ ๋ณด ๋ฐ ํต๊ณ ๊ท์น์ด ์๋์ ์ค์งํ์ง๋ง ๋ณ๋์ ์์ค NAT ์์ ํ๋ ์์ํฌ ๋ด์์ ๋๋ ์๋ฅผ ๋ค์ด ๊ตญ๊ฒฝ์์๋ ๊ทธ๋ค์ง ์ค์ํ์ง ์์ต๋๋ค. ์ฌ๋ฌ ์ฅ์น์ ๋ถ์ฐ๋ฉ๋๋ค.
๊ตฌ์ฑ
์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์์ด ํ์ํฉ๋๋ค.
- ์๋ก์ด ์ปค๋์ ์ฌ์ฉํ์ญ์์ค. ๊ธฐ๋ฅ ์์ฒด๊ฐ ์ปค๋ 4.16์ ๋ฑ์ฅํ๋ค๋ ์ฌ์ค์๋ ๋ถ๊ตฌํ๊ณ ๊ฝค ์ค๋ซ๋์ ์ด ๊ธฐ๋ฅ์ ๋งค์ฐ "์์์ "์ด์๊ณ ์ ๊ธฐ์ ์ผ๋ก ์ปค๋ ํจ๋์ ์ผ์ผ์ผฐ์ต๋๋ค. LTS ์ปค๋ 2019 ๋ฐ 4.19.90๊ฐ ์ถ์๋ 5.4.5๋ XNUMX์์ฏค ๋ชจ๋ ๊ฒ์ด ์์ ํ๋์์ต๋๋ค.
- ์ต์ ๋ฒ์ ์ nftables๋ฅผ ์ฌ์ฉํ์ฌ nftables ํ์์ผ๋ก iptables ๊ท์น์ ๋ค์ ์์ฑํฉ๋๋ค. ๋ฒ์ 0.9.0์์ ์ ํํ ์๋ํฉ๋๋ค.
์์น์ ์ผ๋ก ์ฒซ ๋ฒ์งธ ํญ๋ชฉ์ผ๋ก ๋ชจ๋ ๊ฒ์ด ๋ช
ํํ๋ค๋ฉด ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ์กฐ๋ฆฝ ์ค์ ๊ตฌ์ฑ์ ๋ชจ๋์ ํฌํจํ๋ ๊ฒ์ ์์ง ์๋ ๊ฒ์
๋๋ค(CONFIG_NFT_FLOW_OFFLOAD=m). ๊ทธ๋ฌ๋ฉด ๋ ๋ฒ์งธ ํญ๋ชฉ์ ๋ํ ์ค๋ช
์ด ํ์ํฉ๋๋ค. nftables ๊ท์น์ iptables์ ์์ ํ ๋ค๋ฅด๊ฒ ์ค๋ช
๋ฉ๋๋ค.
NAT ๊ตฌ์ฑ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
#! /usr/sbin/nft -f
table nat {
chain postrouting {
type nat hook postrouting priority 100;
oif <o_if> snat to <pool_addr_start>-<pool_addr_end> persistent
}
}
ํ๋ฆ ์คํ๋ก๋๋ฅผ ์ฌ์ฉํ๋ฉด ์กฐ๊ธ ๋ ๋ณต์กํ์ง๋ง ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค.
#! /usr/sbin/nft -f
table inet filter {
flowtable fastnat {
hook ingress priority 0
devices = { <i_if>, <o_if> }
}
chain forward {
type filter hook forward priority 0; policy accept;
ip protocol { tcp , udp } flow offload @fastnat;
}
}
์ฌ์ค ์ด๊ฒ์ด ์ ์ฒด ์ค์ ์ ๋๋ค. ์ด์ ๋ชจ๋ TCP/UDP ํธ๋ํฝ์ fastnat ํ ์ด๋ธ์ ํฌํจ๋์ด ํจ์ฌ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋ฉ๋๋ค.
์กฐ์ฌ ๊ฒฐ๊ณผ
์ด๊ฒ์ด ์ผ๋ง๋ "ํจ์ฌ ๋ ๋น ๋ฅธ์ง" ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด ๋์ผํ ํ๋์จ์ด(Xeon E5-1650v2), ๋์ผ ๊ตฌ์ฑ, ๋์ผํ Linux ์ปค๋์ ์ฌ์ฉํ์ง๋ง iptables์์ NAT๋ฅผ ์ํํ๋ ๋ ๊ฐ์ ์ค์ ์๋ฒ์ ๋ํ ๋ก๋ ์คํฌ๋ฆฐ์ท์ ์ฒจ๋ถํ๊ฒ ์ต๋๋ค. (NAT4) ๋ฐ nftables (NAT5)์์.
์คํฌ๋ฆฐ์ท์๋ ์ด๋น ํจํท ์์ ๋ํ ๊ทธ๋ํ๊ฐ ์์ง๋ง ์ด๋ค ์๋ฒ์ ๋ก๋ ํ๋กํ์ ๋ณด๋ฉด ํ๊ท ํจํท ํฌ๊ธฐ๊ฐ 800๋ฐ์ดํธ ์ ๋์ด๋ฏ๋ก ๊ทธ ๊ฐ์ ์ต๋ 1.5Mpps์ ์ด๋ฆ
๋๋ค. ๋ณด์๋ค์ํผ, nftables๊ฐ ์๋ ์๋ฒ๋ ์์ฒญ๋ ์ฑ๋ฅ์ ๋ณด์ ํ๊ณ ์์ต๋๋ค. ํ์ฌ ์ด ์๋ฒ๋ 30Mpps์์ ์ต๋ 3Gbit/s๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ 40Gbps์ ๋ฌผ๋ฆฌ์ ๋คํธ์ํฌ ์ ํ์ ์ถฉ์กฑํ๋ ๋์์ ์ฌ์ CPU ๋ฆฌ์์ค๋ฅผ ํ๋ณดํ ์ ์์ต๋๋ค.
์ด ์๋ฃ๊ฐ ์๋ฒ ์ฑ๋ฅ์ ํฅ์์ํค๋ ค๋ ๋คํธ์ํฌ ์์ง๋์ด์๊ฒ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ถ์ฒ : habr.com