10

我正在使用 Ansible 并ufw在我的服务器上设置防火墙。作为ufw规则的一部分,我希望允许来自 Ansible 控制机器的 SSH,但不允许来自其他任何地方。我的问题是 - 获取控制机器本身的 IP 地址以便我可以将其放入规则中的最佳方法是什么?

我知道我可以使用事实来获取运行 playbook 的机器的 IP 地址,但我没有看到任何简单的方法可以为运行 ansible 的机器自动获取它。

如果可能的话,我想避免添加一个新变量来表示它,因为如果它可以自动发现会很好,但如果这是唯一已知的最佳方法,那么我会这样做。

编辑:我发现这个重复的问题与我的相同,但是它也没有得到解答,因此将保持开放状态。

4

6 回答 6

9
{{ ansible_env['SSH_CLIENT'].split() | first }}

有效,但是您必须从默认用户收集有关连接变量的事实,所以八:

  • 在剧本级别设置«gather_facts:是»而不是«成为:是»
  • 更可靠:运行 «setup» 任务(没有 «become: yes» 和在此 «ansible_env» 用法之前 - 在 «pre_tasks» 部分更好)。

如果您使用«become»运行«gather/setup»,稍后您将得到«一个或多个未定义变量:'dict object'没有属性'SSH_CLIENT'»(这是因为sudoed «setup»只能捕获一小部分变量)。

于 2016-09-08T10:28:58.467 回答
3

最简单的方法是添加连接本地

---
 - name: get my public IP
   ipify_facts: api_url=http://api.ipify.org
   connection: local

 - firewalld: rich_rule='rule family=ipv4 source address={{ ipify_public_ip }} accept' permanent=no state=enabled timeout=300
   become: true
于 2016-09-05T18:47:04.150 回答
1

在以下情况下,不同答案中描述的“ipify_facts”方法应该有效:

  1. 您的控制主机只有一个接口,或者如果它有多个接口并且用于到达 ipify api_url 的接口与用于到达远程主机的接口相同,-并且-
  2. 您的控制主机有一个公共 IP(根本没有使用 NAT),或者您的控制主机在 NAT 内部,但远程主机在外部。

如果不满足上述任何一个条件(即,如果您的控制主机有多个接口和/或您的控制主机和远程主机都在 NAT 之后并使用私有地址),那么另一种情况(尽管稍微复杂一些) ) 方法是在 Ansible 中复制以下内容:

$ ip route get 203.0.113.4
203.0.113.4 via 172.26.232.1 dev enp0s3  src 172.26.232.125
                  cache
$

这将向您显示用于到达特定目的地 (203.0.113.4) 的接口和源地址 (172.26.232.125)。

在 Ansible 中实现这一点的一种方法是:

---
- name: Obtain local IP address
  local_action: shell ip route get {{ inventory_hostname }} | awk '{ for (x=1;x<=NF;x++) if ($x=="src") print $(x+1) }'
  register: local_address
  changed_when: false

- name: Print my local address
  debug: msg="Source address towards {{ inventory_hostname }} is {{ local_address.stdout }}"

输出:

$ ansible-playbook test.yml  -i inventory.txt

PLAY [test] ********************************************************************

TASK [Obtain local IP address] *************************************************
ok: [203.0.113.4 -> localhost]

TASK [Print my local address] **************************************************
ok: [203.0.113.4] => {
    "msg": "Source address towards 203.0.113.4 is 172.26.232.125"
}

如果您有多个可通过不同接口访问的远程主机,这也应该有效。

如果您的inventory_hostname 是DNS 主机名而不是数字IP 地址,则需要在“shell”操作中增加一个步骤。

于 2017-11-02T07:50:42.043 回答
1

我刚刚破解了这个解决方案,它奏效了。这是你要找的东西吗?

- debug var="{{hostvars[inventory_hostname]['ansible_env']['SSH_CLIENT'].split(' ')[0]}}"
于 2016-01-01T22:31:28.337 回答
0
{{ ansible_env['SSH_CLIENT'].split() | first }}
于 2016-07-09T15:00:08.667 回答
0
{{ ansible_env['SSH_CLIENT'].split()[0] }}
于 2016-01-02T02:44:46.467 回答