AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 924821
Accepted
EM0
EM0
Asked: 2018-08-04 05:15:09 +0800 CST2018-08-04 05:15:09 +0800 CST 2018-08-04 05:15:09 +0800 CST

测试 UFW 防火墙更改是否会阻止我重新连接

  • 772

我想使用 Ansible 在许多远程 Ubuntu 18.04 机器上管理 UFW 防火墙规则。如果防火墙规则的更改阻止我通过 SSH 重新连接到机器,这将很难修复(赶紧去数据中心,一一输入复杂的 root 密码,手动编辑防火墙配置)。有没有办法测试防火墙规则更改不会阻止我在应用更改之前重新连接?

或者,如果应用了防火墙规则并且我被锁定了,有没有办法自动恢复它们?(我可以自己备份并设置一个 cron 作业来恢复它,然后再次连接并删除该 cron 作业,但也许这样的东西已经存在?)

ubuntu
  • 3 3 个回答
  • 944 Views

3 个回答

  • Voted
  1. Best Answer
    John Mahowald
    2018-08-06T12:35:57+08:002018-08-06T12:35:57+08:00

    未内置在 ufw 模块中。您所做的更改将在下次重新启动或防火墙重新加载时强制执行。

    您可以做的是重新加载防火墙,然后测试与 SSH 端口的新连接。如果失败,请通过仍然打开的持久连接重置 ufw。

    我有一个无聊的实现,称为 ansible -role-ufw。特别注意使用wait_for, 因为wait_for_connection将使用持久连接而不检测故障。

    请注意,这只有一招。当 SSH 损坏时,您仍然需要远程控制台访问。

    • 2
  2. Gerard H. Pille
    2018-08-04T05:41:35+08:002018-08-04T05:41:35+08:00

    手动应用规则,而不保存它们,但在此之前,请在几分钟后安排重新启动或重置当前规则。所以,如果新规则会造成任何伤害,那只会是那几分钟。

    • 1
  3. EM0
    2018-08-11T01:35:45+08:002018-08-11T01:35:45+08:00

    这就是我最终得到的结果,扩展了John Mahowald的代码:

    角色/set_firewall_rules/tasks/main.yml

    # Apply all the requested firewall rules, then try to establish a new SSH connection to the host.
    # If that SSH connection fails then reset the firewall, so the user is not locked out of the machine!
    
    # Make sure the SSH connection details figured out by target_ssh_info can actually be used to connect before the change.
    # If they're not we'd end up resetting the firewall after ANY change.
    - name: Try to SSH before updating firewall
      become: no
      wait_for:
        host: "{{ target_ssh_host }}"
        port: "{{ target_ssh_port }}"
        search_regex: SSH
        timeout: 5
        msg: "Failed to connect to {{ target_ssh_host }}:{{ target_ssh_port }} before firewall rule change"
      connection: local
    
    - name: Set firewall rules
      ufw:
        src: "{{ item.src }}"
        port: "{{ item.port }}"
        proto: "{{ item.proto }}"
        rule: "{{ item.rule }}"
        comment: "{{ item.comment }}"
      register: firewall_rules
      loop: "{{ rules }}"
    
    # Enable/reload the firewall as a separate task, after all rules have been added, so that the order of rules doesn't matter, i.e. we're not locked out
    # if a deny rule comes before an allow rule (as it should).
    - name: Enable and reload firewall
      ufw:
        state: enabled
      register: firewall_enabled
    
    - name: Try to SSH after updating firewall
      become: no
      # wait_for is key here: it establishes a new connection, while wait_for_connection would re-use the existing one
      wait_for:
        host: "{{ target_ssh_host }}"
        port: "{{ target_ssh_port }}"
        search_regex: SSH
        timeout: 5
        msg: "Failed to connect to {{ target_ssh_host }}:{{ target_ssh_port }} after firewall rule change, trying to reset ufw"
      when: firewall_rules.changed or firewall_enabled.changed
      connection: local
      ignore_errors: yes
      register: ssh_after_ufw_change
    
    # Reset the firewall if the new connection failed above. This works (mostly!), because it uses the existing connection
    - name: Reset firewall if unable to SSH
      ufw:
        state: reset
      when:
        - firewall_rules.changed or firewall_enabled.changed
        - ssh_after_ufw_change.failed
    
    # Stop the playbook - the host is now open to the world (firewall is off), which the user really needs to fix ASAP.
    # It's probably better than being locked out of it, though!
    - name: Fail if unable to SSH after firewall change
      fail:
        msg: "Locked out of SSH after firewall rule changes - firewall was reset"
      when:
        - firewall_rules.changed or firewall_enabled.changed
        - ssh_after_ufw_change.failed
    

    角色/set_firewall_rules/meta/main.yml

    ---
    dependencies:
    - { role: target_ssh_info }
    

    角色/target_ssh_info/tasks/main.yml

    # Set target_ssh_host and target_ssh_port facts to the real hostname and port SSH uses to connect.
    
    # ansible_host and ansible_port can be set at the host level to define what Ansible passes to ssh, but ssh then looks up ansible_host in ~/.ssh/config.
    # This role figure out the real hostname it then connects to - useful for establishing a non-SSH connection to the same host.
    # ansible_port is similar, but a little different: if set it overrides the value in ~/.ssh/config.
    
    - name: Get hostname from local SSH config
      shell: "ssh -G '{{ ansible_host | default(inventory_hostname) }}' | awk '/^hostname / { print $2 }'"
      connection: local
      become: no
      register: ssh_host
      changed_when: false
    
    - name: Get port from local SSH config
      shell: "ssh -G '{{ ansible_host | default(inventory_hostname) }}' | awk '/^port / { print $2 }'"
      connection: local
      become: no
      register: ssh_port
      changed_when: false
      when: ansible_port is not defined
    
    # ansible_port overrides whatever is set in .ssh/config
    - name: Set target SSH host and port
      set_fact:
        target_ssh_host: "{{ ssh_host.stdout }}"
        target_ssh_port: "{{ ansible_port | default (ssh_port.stdout) }}"
    

    请注意,ssh -G即使它们没有在 .ssh/config 中被覆盖,它也会返回主机名和端口,即ssh -G arbitrarystring只返回“arbitrarystring”作为主机名和 22 作为端口。

    • 0

相关问题

  • 无法通过 Ubuntu VPN 访问外部网络

  • ubuntu apt-get upgrade - 如何在 shell 中单击确定?

  • VirtualBox 上 Ubuntu 的访客优化技巧 [关闭]

  • 外部硬盘上的 virtualbox 虚拟硬盘驱动器(Vista 主机上的 ubuntu 客户机)

  • 如何在 Ubuntu 上挂载 LVM 分区?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve