Manage multiple server & client computers with SaltStack (finnish)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

27 KiB

Palvelinten hallinta - Harjoitus 3

Disclaimer:

Tämä harjoitus on tehty osana Haaga-Helian Tietojenkäsittelyn koulutusohjelman kurssia Palvelinten hallinta (ICT4TN022, kevät 2018). Kurssin pitäjänä toimii Tero Karvinen, joka on määritellyt tämän harjoituksen tehtävänkuvaukset. Tehtävien vastaukset ovat Pekka Heleniuksen (allekirjoittanut) tuottamia.

SISÄLLYSLUETTELO

b) Tiedosto muotista: tee yksinkertainen SLS-tilatiedosto, joka laittaa muuttujan tiedostoon. Käytä jinjan kontekstimuuttujaa (template: jinja, context: ...).

Vastaus:

Luodaan tiedosto /srv/salt/firstninja.sls seuraavalla sisällöllä (sudo nano /srv/salt/firstninja.sls):

(Tehtävänannon vaatimus täyttyy state:ssa put_my_foo_stuff)

# Author: Pekka Helenius (~Fincer), 2018
hostile_secondgroup:
group.present:
- name: foobar
- gid: 666
- system: True
hostile_user:
user.present:
- name: evilninja
- fullname: Evil Ninja
- uid: 666
- gid: 666
- shell: /bin/bash
- home: /home/foo
- groups:
- foobar
- require:
- group: hostile_secondgroup
put_my_foo_stuff:
file.managed:
- name: /foo/mysecretfoo
- source: salt://foofile
- makedirs: True
- user: 666
- group: 666
- mode: 0744
- template: jinja
- context:
supersecretfoo: 'you never know where this came from'
notsosecretbar: 'wanna beer?'
- require:
- user: hostile_user
foo_executable:
file.symlink:
- name: /usr/local/bin/mysecretfoo
- target: /foo/mysecretfoo
- require:
- file: put_my_foo_stuff
evil_nullfiles:
cmd.run:
- name: 'touch ./foo_everywhere'
- cwd: /foo
- creates: foo_everywhere
- creates: foofoo
- require:
- file: put_my_foo_stuff
identity_crisis:
cmd.run:
- name: /usr/bin/id -a
- runas: evilninja
- require:
- user: hostile_user
haha_execute:
cmd.run:
- shell: /bin/sh
- name: mysecretfoo
- require:
- user: hostile_user
- file: foo_executable

Lisätään masterille tiedosto /srv/salt/foofile seuraavalla sisällöllä (sudo nano /srv/salt/foofile):

#!/bin/sh
echo -e "{{ supersecretfoo }}\n{{ notsosecretbar }}"

Tämä tiedosto kirjoitetaan minionin/minioneiden kohteeseen /foo/mysecretfoo ja luodaan symbolinen linkki /usr/local/bin/mysecretfoo.

Testataan toimivuus harjoituksessa 1 ja 2 käytetyllä master-minion -tietokonekokoonpanolla (master: master, minion: orjakone):

sudo salt 'orjakone' state.apply firstninja

Masterilla tulostettu output:

orjakone:
----------
ID: hostile_secondgroup
Function: group.present
Name: foobar
Result: True
Comment: Group foobar is present and up to date
Started: 21:52:22.010941
Duration: 1.317 ms
Changes:   
----------
ID: hostile_user
Function: user.present
Name: evilninja
Result: True
Comment: User evilninja is present and up to date
Started: 21:52:22.012741
Duration: 13.69 ms
Changes:   
----------
ID: put_my_foo_stuff
Function: file.managed
Name: /foo/mysecretfoo
Result: True
Comment: File /foo/mysecretfoo is in the correct state
Started: 21:52:22.027375
Duration: 10.438 ms
Changes:   
----------
ID: foo_executable
Function: file.symlink
Name: /usr/local/bin/mysecretfoo
Result: True
Comment: Created new symlink /usr/local/bin/mysecretfoo -> /foo/mysecretfoo
Started: 21:52:22.038030
Duration: 26.087 ms
Changes:   
----------
new:
/usr/local/bin/mysecretfoo
----------
ID: evil_nullfiles
Function: cmd.run
Name: touch ./foo_everywhere
Result: True
Comment: Command "touch ./foo_everywhere" run
Started: 21:52:22.066037
Duration: 8.669 ms
Changes:   
----------
pid:
3426
retcode:
0
stderr:
stdout:
----------
ID: identity_crisis
Function: cmd.run
Name: /usr/bin/id -a
Result: True
Comment: Command "/usr/bin/id -a" run
Started: 21:52:22.074865
Duration: 158.997 ms
Changes:   
----------
pid:
3450
retcode:
0
stderr:
stdout:
uid=666(evilninja) gid=666(foobar) groups=666(foobar)
----------
ID: haha_execute
Function: cmd.run
Name: mysecretfoo
Result: True
Comment: Command "mysecretfoo" run
Started: 21:52:22.234242
Duration: 14.473 ms
Changes:   
----------
pid:
3455
retcode:
0
stderr:
stdout:
-e you never know where this came from
wanna beer?
Summary for orjakone
------------
Succeeded: 7 (changed=4)
Failed:    0
------------
Total states run:     7
Total run time: 233.671 ms

c) SLS tilaa Jinjalla: tee yksinkertainen SLS-tilatiedosto, joka käyttää for-in -silmukaa. Voit esimerkiksi tehdä kolme tiedostoa silmukalla. (Tässä tehtävässä siis käytetään jinjaa vain SLS-tiedoston sisällä, älä sotke samaan esimerkkiin tekstitiedostojen sisällön muuttamista.)

Vastaus:

Luodaan master:lle tiedosto /srv/salt/first_jinjaloop.sls seuraavalla sisällöllä (sudo nano /srv/salt/first_jinjaloop.sls):

# Author: Pekka Helenius (~Fincer), 2018
{% for loplop in ['round_1', 'round_2', 'round_3', 'round_4'] %}
loopsloops_noops{{ loop.index }}:
file.managed:
- name: /tmp/loopnoops/{{ loplop }}
- source: salt://loops/jinjaninja_loop
- makedirs: True
- template: jinja
- context:
filenumber: {{ loplop }}
run_fatboy_run_{{ loop.index }}:
cmd.run:
- name: cat /tmp/loopnoops/{{ loplop }}
- require:
- file: loopsloops_noops{{ loop.index }}
{% endfor %}

Luodaan masterilla tiedosto /srv/salt/loops/jinjaninja_loop:

sudo mkdir -p /srv/salt/loops
echo "Loops loops noops {{ filenumber }}" | sudo tee /srv/salt/loops/jinjaninja_loop

Ajetaan luotu state-tiedosto masterilta orjakone-minionille:

sudo salt 'orjakone' state.apply first_jinjaloop

Masterilta saatu output:

orjakone:
----------
ID: loopsloops_noops1
Function: file.managed
Name: /tmp/loopnoops/round_1
Result: True
Comment: File /tmp/loopnoops/round_1 updated
Started: 22:15:48.402678
Duration: 22.99 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: run_fatboy_run_1
Function: cmd.run
Name: cat /tmp/loopnoops/round_1
Result: True
Comment: Command "cat /tmp/loopnoops/round_1" run
Started: 22:15:48.426279
Duration: 9.155 ms
Changes:   
----------
pid:
3654
retcode:
0
stderr:
stdout:
Loops loops noops round_1
----------
ID: loopsloops_noops2
Function: file.managed
Name: /tmp/loopnoops/round_2
Result: True
Comment: File /tmp/loopnoops/round_2 updated
Started: 22:15:48.435550
Duration: 18.288 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: run_fatboy_run_2
Function: cmd.run
Name: cat /tmp/loopnoops/round_2
Result: True
Comment: Command "cat /tmp/loopnoops/round_2" run
Started: 22:15:48.454122
Duration: 5.179 ms
Changes:   
----------
pid:
3656
retcode:
0
stderr:
stdout:
Loops loops noops round_2
----------
ID: loopsloops_noops3
Function: file.managed
Name: /tmp/loopnoops/round_3
Result: True
Comment: File /tmp/loopnoops/round_3 updated
Started: 22:15:48.459403
Duration: 19.723 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: run_fatboy_run_3
Function: cmd.run
Name: cat /tmp/loopnoops/round_3
Result: True
Comment: Command "cat /tmp/loopnoops/round_3" run
Started: 22:15:48.479414
Duration: 6.602 ms
Changes:   
----------
pid:
3658
retcode:
0
stderr:
stdout:
Loops loops noops round_3
----------
ID: loopsloops_noops4
Function: file.managed
Name: /tmp/loopnoops/round_4
Result: True
Comment: File /tmp/loopnoops/round_4 updated
Started: 22:15:48.486128
Duration: 18.883 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: run_fatboy_run_4
Function: cmd.run
Name: cat /tmp/loopnoops/round_4
Result: True
Comment: Command "cat /tmp/loopnoops/round_4" run
Started: 22:15:48.505300
Duration: 9.609 ms
Changes:   
----------
pid:
3660
retcode:
0
stderr:
stdout:
Loops loops noops round_4
Summary for orjakone
------------
Succeeded: 8 (changed=8)
Failed:    0
------------
Total states run:     8
Total run time: 110.429 ms

d) SSH-demonin portti: tee tila, joka asentaa SSH-demonin valittuun porttiin. Käytä portin valintaan Jinjaa, siten että sshd_config:issa “Port:”-kohdan arvo tulee Jinjan muuttujasta.

Vastaus:

HUOM! Koska tehtävänannossa ei pyydetty käyttämään master-koneella sijaitsevaa esimääritettyä SSHD:n konfiguraatiotiedostoa ja pyydettiin vaihtamaan pelkkä SSHD:n yhteysportti minionille/minioneille, on SLS-tiedosto rakennettu tämän esivaatimuksen pohjalta. Yleisesti voidaan haluta samat asetukset kaikille minioneille, jolloin tulee käyttää esimääritettyä SSHD:n konfiguraatiotiedostoa, joka korvaa minionilla/minioneilla olevan tiedoston.

Halusin kokeilla jinja:lla lukujen generointia tässä tehtävässä. Olisi voitu toki käyttää ennalta määriteltyä porttia, mutta hauskempaa generoida jotain satunnaista. Soveltuuko tämä käyttökohteeseen, it's up to you.

SSH-portti generoidaan väliltä 23-600. Käytetään seuraavaa sisältöä uuteen state-tiedostoon.

Luodaan masterille tiedosto srv/salt/ssh_random/init.sls (sudo mkdir -p /srv/salt/ssh_random && sudo nano /srv/salt/ssh_random/init.sls):

# Author: Pekka Helenius (~Fincer), 2018
{% set supersecret_ssh_port = range(23, 600) | random %}
check_sshd_install:
pkg.installed:
- pkgs:
- openssh-server # Ubuntu specific
check_sshd_config:
file.managed:
- name: /etc/ssh/sshd_config
- require:
- pkg: check_sshd_install
check_sshd_current_port:
cmd.run:
- name: 'echo "current SSH daemon port for $(hostname) (Salt ID: {{ grains['id'] }}) is: $(grep -E ^[#P]+ort /etc/ssh/sshd_config)"'
- require:
- file: check_sshd_config
prevent_if_ssh_sessions_open:
cmd.run:
- names: 
- 'SSH_SESSIONS=$(/bin/netstat -ntpa | grep "ESTABLISHED.*sshd"); if [ $(echo $SSH_SESSIONS | wc -w) -gt 1 ]; then echo -e "$(hostname) (Salt ID: {{ grains['id'] }}): The following established SSH session were found:\n$SSH_SESSIONS\n\nNot changing SSH daemon port." && false; fi'
- unset SSH_SESSIONS
- require:
- file: check_sshd_config
- cmd: check_sshd_current_port
new_ssh_port:
file.replace:
- name: /etc/ssh/sshd_config
- pattern: '^[#P]+ort [0-9][0-9]*'
- repl: 'Port {{ supersecret_ssh_port }}'
- require:
- cmd: prevent_if_ssh_sessions_open
sshd_restart:
service.running:
- name: ssh.service # Yes, this is the daemon process
- watch:
- file: new_ssh_port
ssh_new_port_inform:
cmd.run:
- name: 'echo "new SSH daemon port for $(hostname) (Salt ID: {{ grains['id'] }}) is {{ supersecret_ssh_port }}"'
- require:
- service: sshd_restart
- file: new_ssh_port

Ajetaan ssh_random -state masterilta kaikille yhteydessä oleville minioneille:

sudo salt '*' state.apply ssh_random

Masterilla saatu output minionille "orjakone":

orjakone:
----------
ID: check_sshd_install
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 14:26:13.249172
Duration: 416.921 ms
Changes:   
----------
ID: check_sshd_config
Function: file.managed
Name: /etc/ssh/sshd_config
Result: True
Comment: File /etc/ssh/sshd_config exists with proper permissions. No changes made.
Started: 14:26:13.668542
Duration: 1.195 ms
Changes:   
----------
ID: check_sshd_current_port
Function: cmd.run
Name: echo "current SSH daemon port for $(hostname) (Salt ID: orjakone) is: $(grep -E ^[#P]+ort /etc/ssh/sshd_config)"
Result: True
Comment: Command "echo "current SSH daemon port for $(hostname) (Salt ID: orjakone) is: $(grep -E ^[#P]+ort /etc/ssh/sshd_config)"" run
Started: 14:26:13.671432
Duration: 4.479 ms
Changes:   
----------
pid:
2813
retcode:
0
stderr:
stdout:
current SSH daemon port for minion (Salt ID: orjakone) is: Port 22
----------
ID: prevent_if_ssh_sessions_open
Function: cmd.run
Name: SSH_SESSIONS=$(/bin/netstat -ntpa | grep "ESTABLISHED.*sshd"); if [ $(echo $SSH_SESSIONS | wc -w) -gt 1 ]; then echo -e "$(hostname) (Salt ID: orjakone): The following established SSH session were found:\n$SSH_SESSIONS\n\nNot changing SSH daemon port." && false; fi
Result: True
Comment: Command "SSH_SESSIONS=$(/bin/netstat -ntpa | grep "ESTABLISHED.*sshd"); if [ $(echo $SSH_SESSIONS | wc -w) -gt 1 ]; then echo -e "$(hostname) (Salt ID: orjakone): The following established SSH session were found:\n$SSH_SESSIONS\n\nNot changing SSH daemon port." && false; fi" run
Started: 14:26:13.676350
Duration: 13.544 ms
Changes:   
----------
pid:
2816
retcode:
0
stderr:
stdout:
----------
ID: prevent_if_ssh_sessions_open
Function: cmd.run
Name: unset SSH_SESSIONS
Result: True
Comment: Command "unset SSH_SESSIONS" run
Started: 14:26:13.690114
Duration: 3.341 ms
Changes:   
----------
pid:
2823
retcode:
0
stderr:
stdout:
----------
ID: new_ssh_port
Function: file.replace
Name: /etc/ssh/sshd_config
Result: True
Comment: Changes were made
Started: 14:26:13.693988
Duration: 4.119 ms
Changes:   
----------
diff:
--- 
+++ 
@@ -10,7 +10,7 @@
# possible, but leave them commented.  Uncommented options override the
# default value.
-Port 22
+Port 199
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
----------
ID: sshd_restart
Function: service.running
Name: ssh.service
Result: True
Comment: Service restarted
Started: 14:26:13.724516
Duration: 31.875 ms
Changes:   
----------
ssh.service:
True
----------
ID: ssh_new_port_inform
Function: cmd.run
Name: echo "new SSH daemon port for $(hostname) (Salt ID: orjakone) is 199"
Result: True
Comment: Command "echo "new SSH daemon port for $(hostname) (Salt ID: orjakone) is 199"" run
Started: 14:26:13.756793
Duration: 7.15 ms
Changes:   
----------
pid:
2832
retcode:
0
stderr:
stdout:
new SSH daemon port for minion (Salt ID: orjakone) is 199
Summary for orjakone
------------
Succeeded: 8 (changed=6)
Failed:    0
------------
Total states run:     8
Total run time: 482.624 ms

Näyttäisi siltä, että portti 199 on generoitu uudeksi SSH daemonin yhteysportiksi koneelle 'orjakone'. Varmistetaan tietojen oikeellisuus. Tämän voi tehdä etänä SSH-yhteyden avulla muultakin koneelta (testataan yhteyden toimivuus orjakoneen IP:een SSH clientilla porttia 199 käyttäen), mutta tässä varmistamme SSH-yhteyden toimivuuden portissa 199 suoraan minionin näkymästä:

/etc/ssh/sshd_config -tiedoston sisältöä SSH-client testauksineen orjakoneen näkymästä ylläolevan ajon jälkeen:

randomport-from-master

Toinen esimerkki:

randomport-from-master

Lisänä - SSH-portin vaihtamisen estäminen, jos SSH-yhteyksiä on muodostettu minionille

Jos SSH-yhteyksiä on minionilla auki, voimme haluta estää portin vaihtamisen kesken kaiken. Yllä olevassa SLS-tiedostossa tämä on määritetty state:lla prevent_if_ssh_sessions_open.

Masterin output, jos minionilla on SSH-yhteyksiä auki:

orjakone:
----------
ID: check_sshd_install
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 14:29:50.043605
Duration: 390.748 ms
Changes:   
----------
ID: check_sshd_config
Function: file.managed
Name: /etc/ssh/sshd_config
Result: True
Comment: File /etc/ssh/sshd_config exists with proper permissions. No changes made.
Started: 14:29:50.436782
Duration: 1.099 ms
Changes:   
----------
ID: check_sshd_current_port
Function: cmd.run
Name: echo "current SSH daemon port for $(hostname) (Salt ID: orjakone) is: $(grep -E ^[#P]+ort /etc/ssh/sshd_config)"
Result: True
Comment: Command "echo "current SSH daemon port for $(hostname) (Salt ID: orjakone) is: $(grep -E ^[#P]+ort /etc/ssh/sshd_config)"" run
Started: 14:29:50.438437
Duration: 3.965 ms
Changes:   
----------
pid:
2987
retcode:
0
stderr:
stdout:
current SSH daemon port for minion (Salt ID: orjakone) is: Port 379
----------
ID: prevent_if_ssh_sessions_open
Function: cmd.run
Name: SSH_SESSIONS=$(/bin/netstat -ntpa | grep "ESTABLISHED.*sshd"); if [ $(echo $SSH_SESSIONS | wc -w) -gt 1 ]; then echo -e "$(hostname) (Salt ID: orjakone): The following established SSH session were found:\n$SSH_SESSIONS\n\nNot changing SSH daemon port." && false; fi
Result: False
Comment: Command "SSH_SESSIONS=$(/bin/netstat -ntpa | grep "ESTABLISHED.*sshd"); if [ $(echo $SSH_SESSIONS | wc -w) -gt 1 ]; then echo -e "$(hostname) (Salt ID: orjakone): The following established SSH session were found:\n$SSH_SESSIONS\n\nNot changing SSH daemon port." && false; fi" run
Started: 14:29:50.442778
Duration: 11.447 ms
Changes:   
----------
pid:
2990
retcode:
1
stderr:
stdout:
-e minion (Salt ID: orjakone): The following established SSH session were found:
tcp6       0      0 ::1:379                 ::1:36896               ESTABLISHED 2869/sshd: fincer [ 
Not changing SSH daemon port.
----------
ID: prevent_if_ssh_sessions_open
Function: cmd.run
Name: unset SSH_SESSIONS
Result: True
Comment: Command "unset SSH_SESSIONS" run
Started: 14:29:50.454451
Duration: 3.132 ms
Changes:   
----------
pid:
2998
retcode:
0
stderr:
stdout:
----------
ID: new_ssh_port
Function: file.replace
Name: /etc/ssh/sshd_config
Result: False
Comment: One or more requisite failed: ssh_random.prevent_if_ssh_sessions_open
Changes:   
----------
ID: sshd_restart
Function: service.running
Name: ssh.service
Result: False
Comment: One or more requisite failed: ssh_random.new_ssh_port
Changes:   
----------
ID: ssh_new_port_inform
Function: cmd.run
Name: echo "new SSH daemon port for $(hostname) (Salt ID: orjakone) is 258"
Result: False
Comment: One or more requisite failed: ssh_random.sshd_restart, ssh_random.new_ssh_port
Changes:   
Summary for orjakone
------------
Succeeded: 4 (changed=3)
Failed:    4
------------
Total states run:     8
Total run time: 410.391 ms
ERROR: Minions returned with non-zero exit code

prevent-ssh-portchange_

e) Kokeile jonkun toisen opiskelijan tekemää Salt-tilaa. Kokeiltava tila voi olla mistä vain harjoituksesta. Opiskelijoiden raportteja ja koodeja löydät tämän sivun perästä kommenteista.

Vastaus:

Valitaan henkilön Oliver Siren harjoitus 3:n Salt state, Jinja for-in loop -tehtävän vastaus.

Ladataan wget-komennolla init.sls-tiedosto masterilla paikalliseen kansioon /srv/salt/student_sample:

SLS-tiedostossa on oletettu, että tiedosto /srv/salt/jinja/fool.txt on olemassa masterilla. Koska sitä ei ole, me luomme sen alla olevassa komentorimpsussa.

sudo -- sh -c ' \
mkdir -p /srv/salt/student_sample && mkdir -p /srv/salt/jinja && \
wget https://raw.githubusercontent.com/Oliver-Siren/palvelinten-hallinta-ict4tn022-4/master/assignments/h3.md -O /srv/salt/student_sample/init.sls && \
sed -i '51,61!d' /srv/salt/student_sample/init.sls && \
echo "This is your {{ file }}" > /srv/salt/jinja/fool.txt
'

Ajetaan tila masterilta kaikille saataville orja-alkuisille minioneille:

sudo salt 'orja*' state.apply student_sample

Masterilla saatu output:

orjakone:
----------
ID: /tmp/fool/first.txt
Function: file.managed
Result: True
Comment: File /tmp/fool/first.txt updated
Started: 00:16:20.842493
Duration: 25.759 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: /tmp/fool/second.txt
Function: file.managed
Result: True
Comment: File /tmp/fool/second.txt updated
Started: 00:16:20.868344
Duration: 19.281 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: /tmp/fool/third.txt
Function: file.managed
Result: True
Comment: File /tmp/fool/third.txt updated
Started: 00:16:20.887697
Duration: 17.221 ms
Changes:   
----------
diff:
New file
mode:
0644
----------
ID: /tmp/fool/fourth.txt
Function: file.managed
Result: True
Comment: File /tmp/fool/fourth.txt updated
Started: 00:16:20.904989
Duration: 19.971 ms
Changes:   
----------
diff:
New file
mode:
0644
Summary for orjakone
------------
Succeeded: 4 (changed=4)
Failed:    0
------------
Total states run:     4
Total run time:  82.232 ms

Wget:llä ladatun ja sed:llä parsitun esimerkki-SLS -tiedoston sisältö:

{% for tiedosto in ['first.txt', 'second.txt', 'third.txt', 'fourth.txt'] %}
/tmp/fool/{{ tiedosto }}:
file.managed:
- source: salt://jinja/fool.txt
- makedirs: True
- template: jinja
- context:
file: {{ tiedosto }}
{% endfor %}