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

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