30 Ansible für ff@home aufsetzen.page 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. ---
  2. format: markdown
  3. title: Ansible ff@home aufsetzen
  4. toc: yes
  5. ...
  6. # Software
  7. - Debian 12 (bookworm) oder Ubuntu 22.04
  8. - python3 und ansible
  9. ***** Es empfiehlt sich, eine python virtuelle Umgebung zu verwenden *****
  10. Die folgenden Pakete mit Root-Rechten installieren, sofern noch nicht geschehen:
  11. sudo apt install python3-pip python3-venv
  12. Die weiteren Befehle alle als normaler User ausführen.
  13. Im Basisverzeichnis (bei mir /datadisk) die Testumgebung herunterladen mit
  14. git clone https:/...
  15. Für ein neues Projekt ein leeres git anlegen mit
  16. git init
  17. Nun in das git Verzeichnis wechseln (bei mir /datadisk/ffhome) und
  18. die python virtuelle Umgebung einrichten:
  19. python3 -m venv --prompt ffhome .venv
  20. Hierdurch wird in ffhome ein Unterverzeichnis .venv angelegt.
  21. Die virtuelle Umgebung wird in /datadisk/ffhome/.venv eingerichtet und kann aktiviert werden mit
  22. source .venv/bin/activate
  23. Dadurch ändert sich der prompt:
  24. (ffhome) 18:16:41[frankb@berglap /datadisk/ffhome ]
  25. Jetzt kann ansible in der ffhome Umgebung installiert werden:
  26. pip3 install ansible
  27. Damit ist ansible nur in der virtuellen Umgebung installiert und ausführbar.
  28. Zum späteren Verlassen der Umgebung:
  29. deactivate oder Terminal Fenster schliessen
  30. 18:11:20[frankb@berglap /datadisk/ffhome 0]
  31. Die Verzeichnistruktur der Testumgebung
  32. $ tree -L 4 /datadisk/ffhome
  33. /datadisk/ffhome
  34. ├── ansible.cfg
  35. ├── inventory
  36. │   ├── hosts.yaml
  37. │   └── host_vars
  38. |    ├── bergdesk
  39. │      │   ├── vars
  40. │      │   └── vault
  41. │      ├── berghofen
  42. │      │   ├── vars
  43. │      │   └── vault
  44. │      ├── berglap
  45. │      │   ├── vars
  46. │      │   └── vault
  47. │      └── luna
  48. │      ├── vars
  49. │      └── vault
  50. ├── playbooks
  51. │   ├── resources
  52. │   │   └── host
  53. │   │   ├── tincbergdesk.gz
  54. │   │   └── tincberghofen.gz
  55. │   ├── templates
  56. │   │   ├── tinc-up.lan.j2
  57. │   │   └── tinc-up.wan.j2
  58. │   ├── tincbuild.yaml
  59. │   └── update.yaml
  60. Bei den ... sind Zeilen der Übersichtlichkeit halber weggelassen.
  61. Weiter sind auch die versteckten Verzeichnisse .venv und evtl .git nicht aufgeführt.
  62. Die verwendete ansible.cfg:
  63. [defaults]
  64. inventory=./inventory/
  65. roles_path=./roles
  66. playbook_dir=./playbooks/
  67. interpreter_python=auto_silent
  68. #vault_password_file=~/.vault-password
  69. log_path=/tmp/ansible_ffhome.log
  70. cow_selection=random
  71. nocows=True
  72. stdout_callback=yaml
  73. display_args_to_stdout=True
  74. [privilege_escalation]
  75. become=True
  76. [ssh_connection]
  77. pipelining=True
  78. Datei mit den beteiligten Hosts inventory/hosts.yaml
  79. ---
  80. all:
  81. vars:
  82. ansible_port: 24
  83. ansible_user: frankb
  84. ansible_become: true
  85. apus:
  86. hosts:
  87. berghofen:
  88. ansible_host: 192.168.178.51
  89. ansible_user: fb
  90. ansible_become_password: "{{ berghofen_password }}"
  91. desktops:
  92. hosts:
  93. bergdesk:
  94. ansible_host: 192.168.178.201
  95. ansible_become_pass: '{{ bergdesk_password }}'
  96. berglap:
  97. ansible_host: 192.168.178.52
  98. ansible_become_pass: '{{ berglap_password }}'
  99. luna:
  100. ansible_host: 192.168.178.224
  101. ansible_become_pass: '{{ luna_password }}'
  102. altlast:
  103. hosts:
  104. hoerde:
  105. ansible_host: 193.43.220.136
  106. ansible_become: true
  107. ansible_become_method: su
  108. supernodes:
  109. hosts:
  110. 31.172.33.20:
  111. ansible_port: 22
  112. snng-dus01.ffdo.de:
  113. ansible_port: 22
  114. snng-dtm01.ffdo.de:
  115. ansible_port: 22
  116. Die Gruppen apus und desktops enthalten die testhosts, die Gruppen altlast und supernodes sind nicht komplett einbezogen.
  117. Im Verzeichnis inventory/host_vars sind Variablen für die einzelnen hosts, u.a. die passwords, in vars unverschlüsselt, in vault aes256 geschützt. Weiter sind Parameter für tinc enthalten, nur in vars, unverschlüsselt.
  118. Beispielhaft für berghofen
  119. $ cat berghofen/vars
  120. ---
  121. berghofen_password: "{{ vault_berghofen_password }}"
  122. tinc_bindto: 192.168.178.51
  123. wan_broadcast_ip: 193.43.220.191
  124. wan_ip: 193.43.220.162/27
  125. lan_broadcast_ip: 192.168.34.255
  126. lan_ip: 192.168.34.1/24
  127. $ cat berghofen/vault
  128. $ANSIBLE_VAULT;1.2;AES256;xx
  129. 35656536383233636434636533613830303439316263636436363932333636626462616461636537
  130. 3838626266396332363236643361626134393238636133640a646333333866643161356333626564
  131. 32373735343033633666353763376230646137663639373438393537663031643562376365396337
  132. 3161646534666236350a303366373433373833373066353030363766616166666361376637393464
  133. 30613139313661643932373239333865616338653132613530393161656466326561633537383535
  134. 3631356664643139383037636565346630643036353364333866
  135. In der vault Datei (hier Klartext)
  136. ---
  137. vault_berghofen_password: hier das echte PW eintragen
  138. dann die vault Datei verschlüsseln mit
  139. $ ansible-vault encrypt vault --vault-id xxxxx@prompt
  140. anzeigen kann man die Datei mit
  141. $ ansible-vault view vault
  142. und wieder entschlüsseln mit
  143. $ ansible-vault decrypt vault
  144. Es gibt z.Zt. zwei playbooks: update.yaml und tincbuild.yaml
  145. $ cat playbooks/update.yaml
  146. ---
  147. # name: update yaml
  148. - hosts: [desktops,apus,altlast]
  149. tasks:
  150. - name: Testausgabe
  151. debug: msg="Hallo von {{ ansible_hostname }} Ansible managed!"
  152. - name: df -h Aufruf
  153. command: df -h /
  154. changed_when: false
  155. register: df_cmd
  156. - debug:
  157. msg: '{{df_cmd.stdout_lines}} {{ansible_distribution }}'
  158. - name: ping meine hosts
  159. ansible.builtin.ping:
  160. changed_when: false
  161. # - name: Warte auf enter Taste
  162. # ansible.builtin.pause:
  163. - name: Ist flatpak installiert
  164. stat:
  165. path: /usr/bin/flatpak
  166. register: flatpak_file
  167. when: ansible_os_family == "Debian"
  168. - name: Update flatpak Pakete falls snap vh
  169. command: /usr/bin/flatpak update
  170. when: ansible_os_family == "Debian" and flatpak_file.stat.exists
  171. - name: Ist snap installiert
  172. stat:
  173. path: /usr/bin/snap
  174. register: snap_file
  175. when: ansible_os_family == "Debian"
  176. - name: Update snap Pakete falls snap vh
  177. command: /usr/bin/snap refresh
  178. when: ansible_os_family == "Debian" and snap_file.stat.exists
  179. - name: apt update mit upgrade und autoremove
  180. ansible.builtin.apt:
  181. update_cache: yes
  182. cache_valid_time: 3600
  183. autoremove: yes
  184. upgrade: 'yes'
  185. when: ansible_os_family == "Debian"
  186. - stat:
  187. path: /var/run/needrestart
  188. register: needrestart_file
  189. - name: reboot falls erforderlich
  190. ansible.builtin.reboot:
  191. when:
  192. - ansible_os_family == "Debian" and
  193. ( needrestart_file.stat.exists or
  194. rebootreq_file.stat.exists
  195. )
  196. - name: playbook hier beenden bei ! debian
  197. meta: end_play
  198. when: ansible_os_family != "Debian"
  199. $ cat playbooks/tincbuild.yaml
  200. ---
  201. # name: tincbuild yaml
  202. - hosts: [desktops, apus, altlast]
  203. vars:
  204. TINC_VERSION: 1.1pre18
  205. tinc_dev: /dev/net/tun
  206. tinc_mode: switch
  207. tinc_adr_family: ipv4
  208. tinc_max_timeout: 30
  209. tinc_port:
  210. lan: 10001
  211. wan: 661
  212. tasks:
  213. # - name: Show facts available on the system
  214. # ansible.builtin.debug:
  215. # var: ansible_facts
  216. # das folgende klappt leider nicht {{tinc_port.{{ item }}}} syntaxfehler
  217. # geschachtelte variablen gehen nicht.
  218. # - name: willi
  219. # debug: msg="var {{ tinc_port.{{lan}}}}"
  220. - name: Testausgabe
  221. debug: msg="Hallo von {{ ansible_hostname }} Ansible managed!"
  222. - name: df -h Aufruf
  223. command: df -h /
  224. changed_when: false
  225. register: df_cmd
  226. - debug:
  227. msg: '{{df_cmd.stdout_lines}} {{ansible_distribution }}'
  228. # - name: ping meine hosts
  229. # ansible.builtin.ping:
  230. # changed_when: false
  231. # - name: Warte auf enter Taste
  232. # ansible.builtin.pause:
  233. - name: playbook hier beenden bei ! debian
  234. meta: end_play
  235. when: ansible_os_family != "Debian"
  236. - name: Ist tinc Konfigurationsverzeichnis vorhanden
  237. stat:
  238. path: /etc/tinc
  239. register: tinckonf
  240. - name: Gibt es Sicherung von tinc Konfiguration
  241. # ueberlebt keinen reboot
  242. stat:
  243. path: /tmp/tinc{{ ansible_hostname }}.gz
  244. register: tincgz
  245. - name: Konfiguration packen wenn noetig
  246. community.general.archive:
  247. path: /etc/tinc
  248. dest: /tmp/tinc{{ ansible_hostname }}.gz
  249. when: tinckonf.stat.exists
  250. - name: Gesicherte Konfiguration auf Controlnode kopieren
  251. ansible.builtin.fetch:
  252. src: /tmp/tinc{{ ansible_hostname }}.gz
  253. dest: resources/host/
  254. flat: true
  255. when: tinckonf.stat.exists
  256. # - name: Gesicherte Konfiguration auf targetnode loeschen
  257. # file:
  258. # name: /tmp/tinc{{ ansible_hostname }}.gz
  259. # state: absent
  260. # when: tincgz.stat.exists
  261. - name: Abhängigkeiten fuer tinc installieren
  262. apt:
  263. pkg: "{{ item }}"
  264. state: present
  265. with_items:
  266. - build-essential
  267. - libncurses-dev
  268. - libreadline-dev
  269. - pkg-config
  270. - zlib1g-dev
  271. - liblzo2-dev
  272. - libssl-dev
  273. - texinfo
  274. - name: create directory for tinc
  275. file:
  276. name: /opt/tinc
  277. state: directory
  278. - name: Download tinc source
  279. get_url:
  280. url: "https://www.tinc-vpn.org/packages/tinc-{{TINC_VERSION}}.tar.gz"
  281. dest: /opt/tinc/tinc-{{TINC_VERSION}}.tar.gz
  282. register: gettinc
  283. - name: tinc-Quellen entpacken
  284. unarchive:
  285. src: /opt/tinc/tinc-{{TINC_VERSION}}.tar.gz
  286. dest: /usr/src
  287. remote_src: true
  288. when:
  289. - gettinc.changed
  290. - name: Pruefen tinc programm vh
  291. stat:
  292. path: /usr/sbin/tinc
  293. register: tinc_bin
  294. - name: tinc kompilieren und installieren
  295. shell: "cd /usr/src/tinc-{{TINC_VERSION}}
  296. && ./configure --prefix=/usr --sysconfdir=/etc --runstatedir=/run
  297. --localstatedir=/var --with-systemd
  298. && make
  299. && make install"
  300. when:
  301. - tinc_bin.stat.exists == False or gettinc.changed
  302. - name: Gibt es schon eine (alte) tinc Konfiguration
  303. stat:
  304. path: /etc/tinc
  305. register: tinc_etc
  306. - name: tinc Konfigurationsreste beseitigen
  307. file:
  308. path: /etc/tinc
  309. state: absent
  310. when:
  311. - tinc_etc.stat.exists
  312. - name: tinc lan/wan vorkonfigurieren in mehreren Schritten
  313. shell: "tinc --net={{ item }} init {{ansible_hostname}}"
  314. with_items:
  315. - lan
  316. - wan
  317. # when:
  318. # - tinc_bin.stat.exists == False or gettinc.changed
  319. - name: 2048er priv und pub keys löschen
  320. shell: "rm /etc/tinc/{{ item }}/*.priv
  321. && rm /etc/tinc/{{ item }}/hosts/*"
  322. with_items:
  323. - lan
  324. - wan
  325. # when:
  326. # - tinc_bin.stat.exists == False or gettinc.changed
  327. - name: 4096er keys generieren
  328. shell: "tinc --net={{ item }} -b generate-keys 4096"
  329. with_items:
  330. - lan
  331. - wan
  332. # when:
  333. # - tinc_bin.stat.exists == False or gettinc.changed
  334. - name: tinc.conf einrichten
  335. shell: "tinc --net={{ item }} set Device {{tinc_dev}}
  336. && tinc --net={{ item }} set Mode {{tinc_mode}}
  337. && tinc --net={{ item }} set AddressFamily {{tinc_adr_family}}
  338. && tinc --net={{ item }} set MaxTimeout {{tinc_max_timeout}}
  339. && tinc --net={{ item }} set BindToAddress {{tinc_bindto}}"
  340. with_items:
  341. - lan
  342. - wan
  343. # when:
  344. # - tinc_bin.stat.exists == False or gettinc.changed
  345. - name: lan/wan ports setzen
  346. # das geht leider nicht in loop, da Variablen nicht geschachtelt
  347. shell: "tinc --net=lan set Port {{ tinc_port.lan }}
  348. && tinc --net=wan set Port {{ tinc_port.wan }}"
  349. - name: tinc-up anpassen
  350. ansible.builtin.template:
  351. src: templates/tinc-up.{{ item }}.j2
  352. dest: /etc/tinc/{{ item }}/tinc-up
  353. with_items:
  354. - lan
  355. - wan
  356. # when:
  357. # - tinc_bin.stat.exists == False or gettinc.changed
  358. - meta: end_play
  359. Für tinc-up werden folgende templates verwendet
  360. $ cat playbooks/templates/tinc-up.lan.j2
  361. #!/bin/sh
  362. ip addr add {{ lan_ip }} brd {{ lan_broadcast_ip }} dev $INTERFACE
  363. ip link set $INTERFACE mtu 1504 up
  364. $ cat playbooks/templates/tinc-up.wan.j2
  365. #!/bin/sh
  366. ip addr add {{ wan_ip }} brd {{ wan_broadcast_ip }} dev $INTERFACE
  367. ip link set $INTERFACE mtu 1504 up
  368. Aufruf der beiden playbooks mit
  369. $ ansible-playbook -b playbooks/update.yaml -i inventory/hosts.yaml --ask-vault-pass
  370. $ ansible-playbook -b playbooks/tincbuild.yaml -i inventory/hosts.yaml --ask-vault-pass
  371. Gekürzte Ausgabe:
  372. (ffhome) 20:55:59[frankb@berglap /datadisk/ffhome 4] ansible-playbook -b playbooks/update.yaml -i inventory/hosts.yaml --ask-vault-pass
  373. Vault password:
  374. PLAY [desktops,apus,altlast] ***************************************************************
  375. TASK [Gathering Facts] *********************************************************************
  376. [WARNING]: Platform linux on host berglap is using the discovered Python interpreter at
  377. /usr/bin/python3.10, but future installation of another Python interpreter could change the
  378. meaning of that path. See https://docs.ansible.com/ansible-
  379. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  380. ok: [berglap]
  381. [WARNING]: Platform linux on host bergdesk is using the discovered Python interpreter at
  382. /usr/bin/python3.11, but future installation of another Python interpreter could change the
  383. meaning of that path. See https://docs.ansible.com/ansible-
  384. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  385. ok: [bergdesk]
  386. fatal: [luna]: UNREACHABLE! => changed=false
  387. msg: 'Failed to connect to the host via ssh: ssh: connect to host 192.168.178.224 port 24: No route to host'
  388. unreachable: true
  389. [WARNING]: Platform linux on host berghofen is using the discovered Python interpreter at
  390. /usr/bin/python3.11, but future installation of another Python interpreter could change the
  391. meaning of that path. See https://docs.ansible.com/ansible-
  392. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  393. ok: [berghofen]
  394. [WARNING]: Platform freebsd on host hoerde is using the discovered Python interpreter at
  395. /usr/local/bin/python3.9, but future installation of another Python interpreter could
  396. change the meaning of that path. See https://docs.ansible.com/ansible-
  397. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  398. ok: [hoerde]
  399. TASK [Testausgabe] *************************************************************************
  400. ok: [bergdesk] =>
  401. msg: Hallo von bergdesk Ansible managed!
  402. ok: [berglap] =>
  403. msg: Hallo von berglap Ansible managed!
  404. ok: [berghofen] =>
  405. msg: Hallo von berghofen Ansible managed!
  406. ok: [hoerde] =>
  407. msg: Hallo von hoerde Ansible managed!
  408. TASK [df -h Aufruf] ************************************************************************
  409. ok: [berglap]
  410. ok: [bergdesk]
  411. ok: [berghofen]
  412. ok: [hoerde]
  413. TASK [debug] *******************************************************************************
  414. ok: [bergdesk] =>
  415. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/sdb1 439G 98G 319G 24% /''] Debian'
  416. ok: [berglap] =>
  417. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/mapper/system-root 444G 298G 124G 71% /''] Ubuntu'
  418. ok: [berghofen] =>
  419. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/sda6 18G 5,1G 12G 30% /''] Debian'
  420. ok: [hoerde] =>
  421. msg: '[''Filesystem Size Used Avail Capacity Mounted on'', ''s3pool25/jail/hoerde.ffdo.net 3.9G 891M 3.0G 22% /''] FreeBSD'
  422. TASK [ping meine hosts] ********************************************************************
  423. ok: [berglap]
  424. ok: [bergdesk]
  425. ok: [berghofen]
  426. ok: [hoerde]
  427. ...
  428. PLAY RECAP *********************************************************************************
  429. bergdesk : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  430. berghofen : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  431. berglap : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  432. hoerde : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
  433. luna : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0