# Addrtype

## `--match addrtype [options]`

`--match`可以简写为`-m`。常用的`options`有

* `[!] --src-type <type>`

  源地址类型，前面加`!`表示“源地址不是`<type>`类型”
* `[!] --dst-type <type>`

  目的地址类型，前面加`!`表示“目的地址不是`<type>`类型”

`type`的值有`LOCAL`、`MULTICAST`等

## 示例

* 源地址为`LOCAL`类型

```
$ iptables -t nat -A PREROUTING -m addrtype --src-type LOCAL -j TARGET
```

* 目的地址为`LOCAL`类型

```
$ iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j TARGET
```

## 实际场景

### 场景一：kubernetes之nodeport

在k8s中，我们有时候会用`NodePort`的方法对外暴露一个服务。也就是说我们可以通过主机的IP加端口来访问这个服务。这个IP有很多，命令`ip addr`看到的都可以用。比如

```
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:e8:b0:38 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.103/24 brd 192.168.1.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::4876:bfe:de57:eb31/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:9d:c9:79:d8 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
```

那么我们可以在本机上通过`127.0.0.1:port`、`192.168.1.103:port`或`172.17.0.1:port`来访问这个服务；在其他主机上可以通过`192.168.1.103:port`来访问这个服务。

在访问`IP:Port`时，由于最终要转换到Pod的IP与Pod的Port，也就是说，当从外面访问本机的包到达时，要先进入一条链判断是否做DNAT，而这条链就是`KUBE-NODEPORTS`，当然目地地址不是本机就不需要进入`KUBE-NODEPORTS`链了。所以k8s会在`KUBE-SERVICES`链中加入这样一条规则：

```
$ iptables -t nat -A KUBE-SERVICES -m addrtype --dst-type LOCAL -j KUBE-NODEPORT
```

**这个`LOCAL`就是上面`ip addr`显示的IP地址的集合**

我们可以查看这条规则：

```
$ iptables -t nat -nL KUBE-SERVICES
...
KUBE-NODEPORTS  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL
```

### 场景二：calico

to be continued
