Major work complete
- Added some documentation for setup process - Added productivity tools to configuration - Refactored artwork location - Improved Ansible privilege escalation - Default to 720p profilemaster
parent
b054a9a67a
commit
d1831d7044
99
README.md
99
README.md
|
@ -1,2 +1,101 @@
|
|||
|
||||
# fossasia-video
|
||||
|
||||
The FOSSASIA video recording setup
|
||||
|
||||
## Overview
|
||||
|
||||
## Installing Debian
|
||||
|
||||
For the recording machines, get a fresh copy of Debian, and install it with the following settings:
|
||||
|
||||
- Username: opentech
|
||||
- Hostname: model-increment
|
||||
- Example: x220-01
|
||||
- Add GNOME Desktop
|
||||
- Add OpenSSH Server
|
||||
|
||||
If a GNOME Desktop and SSH daemon is already installed, a reinstall is not required but recommended.
|
||||
|
||||
## WireGuard
|
||||
|
||||
To set up the overlay WireGuard network to manage machines everywhere, a server needs to be set up. [`wireguard-negotiator`](https://github.com/serverwentdown/wireguard-negotiator) is a tool written to automate some of the key exchange, that must be run on a publicly accessible server as root:
|
||||
|
||||
```
|
||||
# Create WireGuard interface
|
||||
ip link add dev wg1 type wireguard
|
||||
ip addr add fd11:f055:a514:0000::1/64 dev wg1
|
||||
# Configure the interface once. Assumes the configuration file exists
|
||||
# See WireGuard docs on how to write this configuraion file
|
||||
wg setconf wg1 /etc/wireguard/wg1.conf
|
||||
# Bring up the interface
|
||||
ip link set wg1 up
|
||||
wireguard-negotiator server -i wg1 -e [hostname] -l :8080 -I -B
|
||||
```
|
||||
|
||||
On every recording machine, the client can be easily configured like so:
|
||||
|
||||
```
|
||||
# For now, we have to manually install WireGuard
|
||||
echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee /etc/apt/sources.list.d/unstable.list
|
||||
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' | sudo tee /etc/apt/preferences.d/limit-unstable
|
||||
sudo apt update
|
||||
sudo apt install wireguard
|
||||
# TODO: validate this section
|
||||
sudo systemctl enable --now systemd-networkd
|
||||
wget -O wgn http://[hostname]:8080
|
||||
chmod +x wgn
|
||||
sudo ./wgn request -s http://[hostname]:8080
|
||||
```
|
||||
|
||||
## Configuring Rooms
|
||||
|
||||
To specify the room for a specific host, do the following:
|
||||
|
||||
```
|
||||
echo the_room_id > ~opentech/room_id
|
||||
echo teh_room_type > ~opentech/room_type
|
||||
```
|
||||
|
||||
This step is optional. This and the following steps should be done for every change in room or setup of the laptop.
|
||||
|
||||
## Exporting Hosts
|
||||
|
||||
Export all hosts on the overlay network from WireGuard configuration:
|
||||
|
||||
```
|
||||
wireguard-negotiator dump > wireguard.list
|
||||
```
|
||||
|
||||
This list of IPs can be exported into our Ansible hosts format as such:
|
||||
|
||||
```
|
||||
go run event-generate.go opentech < wireguard.list > event
|
||||
```
|
||||
|
||||
The script `event-fetch-generate.sh` does the exporting and generating of the `event` inventory.
|
||||
|
||||
## Running Playbooks
|
||||
|
||||
Before running any Playbooks, switch to SSH authentication:
|
||||
|
||||
```
|
||||
ansible-playbook -Kf 8 -kc paramiko -i event ssh-key.yml
|
||||
ansible -Kf 8 -kc paramiko -b -i event all -a reboot
|
||||
```
|
||||
|
||||
Now, plays can be run like so:
|
||||
|
||||
```
|
||||
./play [inventory] [playbook]
|
||||
# Which executes the following command
|
||||
ansible-playbook -Kf 4 -i [inventory] [playbook]
|
||||
# Example:
|
||||
./play event recorders.yml
|
||||
```
|
||||
|
||||
## Install Wireless Drivers
|
||||
|
||||
```
|
||||
ansible -Kf 8 -b -i event all -a 'apt install firmware-iwlwifi'
|
||||
```
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[recorders:children]
|
||||
testgroup
|
||||
|
||||
[testgroup]
|
||||
#user@10.10.2.5 room_id=test
|
||||
ambrose@10.10.0.90 room_id=test
|
||||
[recorders]
|
||||
x220-01 ansible_host=fd11:f055:a514::2 ansible_user=opentech room_id= room_type=
|
||||
x230-01 ansible_host=fd11:f055:a514::3 ansible_user=opentech room_id=testroom1 room_type=special
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "Fetching event inventory"
|
||||
|
||||
ssh saguaro /usr/local/bin/wireguard-negotiator dump -i wg1 | go run event-generate.go opentech > event
|
|
@ -0,0 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := bufio.NewScanner(os.Stdin)
|
||||
if len(os.Args) != 1+1 {
|
||||
fmt.Fprintf(os.Stderr, "not enough arguments\nusage: %s [ssh user]\n", os.Args[0])
|
||||
return
|
||||
}
|
||||
user := os.Args[1]
|
||||
|
||||
fmt.Printf("[recorders]\n")
|
||||
|
||||
for s.Scan() {
|
||||
host := s.Text()
|
||||
if strings.HasPrefix(host, "#") {
|
||||
// Is a comment
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(host, ":0") {
|
||||
// Is a "system" host
|
||||
continue
|
||||
}
|
||||
hostname, roomId, roomType, err := discover(host, user)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "host %s discovery failed: %v\n", host, err)
|
||||
}
|
||||
fmt.Printf("%s ansible_host=%s ansible_user=%s room_id=%s room_type=%s\n", hostname, host, user, roomId, roomType)
|
||||
}
|
||||
}
|
||||
|
||||
func discover(host, user string) (hostname, roomId, roomType string, err error) {
|
||||
cmd := exec.Command("/usr/bin/ssh", "-l", user, host, "sh", "-c", "hostname; cat room_id; cat room_type; exit 0")
|
||||
fmt.Fprintf(os.Stderr, "command: %s\n", cmd)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hostname, err = out.ReadString('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hostname = strings.TrimSpace(hostname)
|
||||
roomId, _ = out.ReadString('\n')
|
||||
roomId = strings.TrimSpace(roomId)
|
||||
roomType, _ = out.ReadString('\n')
|
||||
roomType = strings.TrimSpace(roomType)
|
||||
return
|
||||
}
|
|
@ -3,6 +3,11 @@
|
|||
room_id: unknown
|
||||
|
||||
# Overwrite in inventory if cannot cope
|
||||
record_profile: 1080p
|
||||
record_profile: 720p
|
||||
# Overwrite in inventory if want to use more storage to use less CPU
|
||||
record_fast: false
|
||||
|
||||
record_user: mixer
|
||||
record_home: /home/mixer
|
||||
|
||||
autostart: true
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
ansible-playbook -Kbf 1 -i "$1" "$2"
|
||||
set -e
|
||||
|
||||
ansible-playbook -Kf 4 -i "$1" "$2"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
- hosts: recorders
|
||||
roles:
|
||||
- productivity
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
- hosts: recorders
|
||||
roles:
|
||||
- role: recorder
|
||||
- role: monitoring-client
|
||||
vars:
|
||||
autostart: false
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
|
||||
# Credits: Michael Heap
|
||||
|
||||
- name: Does the Google apt file exist?
|
||||
become: yes
|
||||
command: test -f {{ apt_file }}
|
||||
register: google_apt_exists
|
||||
ignore_errors: True
|
||||
|
||||
- name: Add Google Chrome key
|
||||
become: yes
|
||||
shell: wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
|
||||
when: google_apt_exists.rc == 1
|
||||
|
||||
- name: Add Google Chrome repo
|
||||
become: yes
|
||||
copy: content="deb http://dl.google.com/linux/chrome/deb/ stable main" dest={{ apt_file }} owner=root group=root mode=644
|
||||
when: google_apt_exists.rc == 1
|
||||
|
||||
- name: Update apt cache
|
||||
become: yes
|
||||
apt: update_cache=yes
|
||||
when: google_apt_exists.rc == 1
|
||||
|
||||
- name: Install Google Chrome
|
||||
become: yes
|
||||
apt:
|
||||
state: latest
|
||||
pkg: google-chrome-stable
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
- include: chrome.yml
|
||||
vars:
|
||||
- apt_file: /etc/apt/sources.list.d/google-chrome.list
|
||||
- include: vscode.yml
|
||||
vars:
|
||||
- apt_file: /etc/apt/sources.list.d/vscode.list
|
||||
- include: packages.yml
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
|
||||
- name: install editors
|
||||
become: yes
|
||||
apt:
|
||||
state: latest
|
||||
name:
|
||||
- neovim
|
||||
- emacs
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
|
||||
# Credits: Michael Heap
|
||||
|
||||
- name: Does the vscode apt file exist?
|
||||
become: yes
|
||||
command: test -f {{ apt_file }}
|
||||
register: vscode_apt_exists
|
||||
ignore_errors: True
|
||||
|
||||
- name: Add Microsoft key
|
||||
become: yes
|
||||
shell: wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
|
||||
when: vscode_apt_exists.rc == 1
|
||||
|
||||
- name: Add vscode repo
|
||||
become: yes
|
||||
copy: content="deb https://packages.microsoft.com/repos/vscode stable main" dest={{ apt_file }} owner=root group=root mode=644
|
||||
when: vscode_apt_exists.rc == 1
|
||||
|
||||
- name: Update apt cache
|
||||
become: yes
|
||||
apt: update_cache=yes
|
||||
when: vscode_apt_exists.rc == 1
|
||||
|
||||
- name: Install vscode
|
||||
become: yes
|
||||
apt:
|
||||
state: latest
|
||||
pkg: code
|
|
@ -2,19 +2,17 @@
|
|||
|
||||
- name: create artwork directory
|
||||
file:
|
||||
dest: "/opt/artwork/{{ event.id }}"
|
||||
dest: "{{ mixer_user.home }}/artwork/{{ event.id }}"
|
||||
state: directory
|
||||
recurse: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
||||
- name: copy backgrounds
|
||||
copy:
|
||||
src: "../../../artwork/{{ event.id }}/{{ item }}.png"
|
||||
dest: "/opt/artwork/{{ event.id }}"
|
||||
owner: root
|
||||
group: root
|
||||
dest: "{{ mixer_user.home }}/artwork/{{ event.id }}"
|
||||
mode: u=rw,g=r,o=r
|
||||
with_items:
|
||||
- side-by-side
|
||||
|
@ -22,3 +20,5 @@
|
|||
- side-by-side-43
|
||||
- side-by-side-43-reverse
|
||||
- blank
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
---
|
||||
|
||||
- name: generate hosts file
|
||||
become: yes
|
||||
template:
|
||||
src: etc-hosts.j2
|
||||
dest: /etc/hosts
|
||||
|
||||
- name: set hostname to room_id
|
||||
become: yes
|
||||
hostname:
|
||||
name: "room-{{ room_id }}"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
- include: user.yml
|
||||
- include: hostname.yml
|
||||
#- include: hostname.yml
|
||||
- include: packages.yml
|
||||
- include: artwork.yml
|
||||
- include: obs.yml
|
||||
|
|
|
@ -5,39 +5,39 @@
|
|||
dest: "{{ mixer_user.home }}/.config/obs-studio/{{ item }}"
|
||||
state: directory
|
||||
recurse: yes
|
||||
owner: mixer
|
||||
group: mixer
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
with_items:
|
||||
- basic/profiles/1080p
|
||||
- basic/profiles/720p
|
||||
- basic/scenes
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
||||
- name: create videos directory
|
||||
file:
|
||||
dest: "{{ mixer_user.home }}/Videos/{{ event.id }}/{{ room_id }}"
|
||||
state: directory
|
||||
recurse: yes
|
||||
owner: mixer
|
||||
group: mixer
|
||||
mode: u=rwx,g=rx,o=rx
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
||||
- name: generate base obs configuration files
|
||||
template:
|
||||
src: "obs-studio/{{ item }}.j2"
|
||||
dest: "{{ mixer_user.home }}/.config/obs-studio/{{ item }}"
|
||||
owner: mixer
|
||||
group: mixer
|
||||
mode: u=rw,g=r,o=r
|
||||
with_items:
|
||||
- global.ini
|
||||
- basic/profiles/1080p/basic.ini
|
||||
- basic/profiles/720p/basic.ini
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
||||
- name: generate event obs configuration files
|
||||
template:
|
||||
src: "obs-studio/basic/scenes/event_id.json.j2"
|
||||
dest: "{{ mixer_user.home }}/.config/obs-studio/basic/scenes/{{ event.id }}.json"
|
||||
owner: mixer
|
||||
group: mixer
|
||||
mode: u=rw,g=r,o=r
|
||||
become: yes
|
||||
become_user: mixer
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
---
|
||||
|
||||
- name: install general packages
|
||||
become: yes
|
||||
apt:
|
||||
state: latest
|
||||
name:
|
||||
- git
|
||||
|
||||
- name: install packages required to be a recorder
|
||||
become: yes
|
||||
apt:
|
||||
state: latest
|
||||
name:
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
---
|
||||
|
||||
- name: create mixer group
|
||||
become: yes
|
||||
group:
|
||||
name: mixer
|
||||
|
||||
- name: create mixer user with password mixer
|
||||
become: yes
|
||||
user:
|
||||
name: mixer
|
||||
group: mixer
|
||||
|
@ -14,7 +16,8 @@
|
|||
register: mixer_user
|
||||
|
||||
- name: enable gdm autologin to mixer user
|
||||
copy:
|
||||
become: yes
|
||||
template:
|
||||
src: gdm.conf
|
||||
dest: /etc/gdm3/daemon.conf
|
||||
owner: root
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
# Uncomment the line below to force the login screen to use Xorg
|
||||
#WaylandEnable=false
|
||||
|
||||
{% if autostart %}
|
||||
# Enabling automatic login
|
||||
AutomaticLoginEnable = true
|
||||
AutomaticLogin = mixer
|
||||
{% endif %}
|
||||
|
||||
# Enabling timed login
|
||||
# TimedLoginEnable = true
|
|
@ -11,7 +11,7 @@ OutputCY=1080
|
|||
Mode=Simple
|
||||
|
||||
[Audio]
|
||||
SampleRate=48000
|
||||
SampleRate=44100
|
||||
|
||||
[Hotkeys]
|
||||
OBSBasic.StartRecording={\n "bindings": [\n {\n "control": true,\n "key": "OBS_KEY_RETURN"\n }\n ]\n}
|
||||
|
@ -20,7 +20,8 @@ OBSBasic.Transition={\n "bindings": [\n {\n "key": "OBS_KEY
|
|||
|
||||
[SimpleOutput]
|
||||
RecFormat=mkv
|
||||
RecQuality=Small
|
||||
RecQuality=Stream
|
||||
VBitrate=3000
|
||||
{% if record_fast %}
|
||||
RecEncoder=x264_lowcpu
|
||||
{% else %}
|
||||
|
|
|
@ -11,7 +11,7 @@ OutputCY=720
|
|||
Mode=Simple
|
||||
|
||||
[Audio]
|
||||
SampleRate=48000
|
||||
SampleRate=44100
|
||||
|
||||
[Hotkeys]
|
||||
OBSBasic.StartRecording={\n "bindings": [\n {\n "control": true,\n "key": "OBS_KEY_RETURN"\n }\n ]\n}
|
||||
|
@ -20,7 +20,8 @@ OBSBasic.Transition={\n "bindings": [\n {\n "key": "OBS_KEY
|
|||
|
||||
[SimpleOutput]
|
||||
RecFormat=mkv
|
||||
RecQuality=Small
|
||||
RecQuality=Stream
|
||||
VBitrate=3000
|
||||
{% if record_fast %}
|
||||
RecEncoder=x264_lowcpu
|
||||
{% else %}
|
||||
|
|
|
@ -159,7 +159,7 @@
|
|||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"settings": {
|
||||
"file": "/opt/artwork/{{ event.id }}/blank.png",
|
||||
"file": "{{ mixer_user.home }}/artwork/{{ event.id }}/blank.png",
|
||||
"unload": true
|
||||
},
|
||||
"sync": 0,
|
||||
|
@ -446,7 +446,7 @@
|
|||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"settings": {
|
||||
"file": "/opt/artwork/{{ event.id }}/side-by-side-43-reverse.png",
|
||||
"file": "{{ mixer_user.home }}/artwork/{{ event.id }}/side-by-side-43-reverse.png",
|
||||
"unload": true
|
||||
},
|
||||
"sync": 0,
|
||||
|
@ -609,7 +609,7 @@
|
|||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"settings": {
|
||||
"file": "/opt/artwork/{{ event.id }}/side-by-side-43.png",
|
||||
"file": "{{ mixer_user.home }}/artwork/{{ event.id }}/side-by-side-43.png",
|
||||
"unload": true
|
||||
},
|
||||
"sync": 0,
|
||||
|
@ -913,7 +913,7 @@
|
|||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"settings": {
|
||||
"file": "/opt/artwork/{{ event.id }}/side-by-side.png",
|
||||
"file": "{{ mixer_user.home }}/artwork/{{ event.id }}/side-by-side.png",
|
||||
"unload": false
|
||||
},
|
||||
"sync": 0,
|
||||
|
@ -1103,7 +1103,7 @@
|
|||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"settings": {
|
||||
"file": "/opt/artwork/{{ event.id }}/side-by-side-reverse.png",
|
||||
"file": "{{ mixer_user.home }}/artwork/{{ event.id }}/side-by-side-reverse.png",
|
||||
"unload": false
|
||||
},
|
||||
"sync": 0,
|
||||
|
|
|
@ -9,8 +9,8 @@ cx=720
|
|||
cy=580
|
||||
|
||||
[BasicWindow]
|
||||
geometry=AdnQywACAAAAAABDAAAAGwAAA/8AAAL/AAAAWAAAAEYAAAOuAAACwgAAAAACAAAABAA=
|
||||
DockState=AAAA/wAAAAD9AAAAAQAAAAMAAAO9AAAA+/wBAAAABfsAAAAUAHMAYwBlAG4AZQBzAEQAbwBjAGsBAAAAAAAAANsAAACoAP////sAAAAWAHMAbwB1AHIAYwBlAHMARABvAGMAawEAAADhAAAA3AAAAKgA////+wAAABIAbQBpAHgAZQByAEQAbwBjAGsBAAABwwAAASoAAADkAP////sAAAAeAHQAcgBhAG4AcwBpAHQAaQBvAG4AcwBEAG8AYwBrAAAAAlgAAAC/AAAAggD////7AAAAGABjAG8AbgB0AHIAbwBsAHMARABvAGMAawEAAALzAAAAygAAAJsA////AAADvQAAAZkAAAAEAAAABAAAAAgAAAAI/AAAAAA=
|
||||
geometry=AdnQywACAAAAAAAAAAAAGwAABVUAAAL/AAAAAAAAAEAAAAQ2AAAC/wAAAAACAAAABVY=
|
||||
DockState=AAAA/wAAAAD9AAAAAQAAAAMAAAVWAAABF/wBAAAABfsAAAAUAHMAYwBlAG4AZQBzAEQAbwBjAGsBAAAAAAAAAToAAACoAP////sAAAAWAHMAbwB1AHIAYwBlAHMARABvAGMAawEAAAFAAAABPAAAAKgA////+wAAABIAbQBpAHgAZQByAEQAbwBjAGsBAAACggAAAawAAADkAP////sAAAAeAHQAcgBhAG4AcwBpAHQAaQBvAG4AcwBEAG8AYwBrAAAAAlgAAAC/AAAAggD////7AAAAGABjAG8AbgB0AHIAbwBsAHMARABvAGMAawEAAAQ0AAABIgAAAJoA////AAAFVgAAAXIAAAAEAAAABAAAAAgAAAAI/AAAAAA=
|
||||
PreviewEnabled=true
|
||||
AlwaysOnTop=false
|
||||
SceneDuplicationMode=true
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- hosts: recorders
|
||||
tasks:
|
||||
- name: set permissions for .ssh directory
|
||||
file:
|
||||
path: "{{ ansible_env.HOME }}/.ssh"
|
||||
state: directory
|
||||
mode: u=rwx,g=-rwx,o=-rwx
|
||||
- name: create authorized_keys file
|
||||
file:
|
||||
path: "{{ ansible_env.HOME }}/.ssh/authorized_keys"
|
||||
state: touch
|
||||
mode: u=rwx,g=r-wx,o=r-wx
|
||||
- name: insert ambrose's public ssh key
|
||||
blockinfile:
|
||||
dest: "{{ ansible_env.HOME }}/.ssh/authorized_keys"
|
||||
block: |
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDDBsAEpJLRUzF9O58EkRFAe+WFp46SNEEz6ChOEkzWs+Vn4b60uKABXB60l56S1Ok6PHlNxyIlLuF+IXUOfalO+V9HXxZmjdHp7SibOXcEDFRDnCgGqnRTwd5zEbdMnZ9g0ia7NnIeaS7M5pXGtir7S86pNNaVWWnBvobDuc1As4NGIHa7hPHPOsPRgjNgB6YqaRq6a98j1yGghMiQJJvsBeZ0S00MZp9lfUiB+jrxhDgGyPsU5M9U+ObJmOFlaLx5XqZW3/5tTJoEmyD/vRV6IzOhhR6PPgGpQXJBdmrbJOKWtTwckwWE2xR+rs3J154OyZadkJ9+1aj/EKleTYs5GfDzGQeTb/wsyRz3tgTesFcXW/klVYVEcvZZxPvOoMPUK8vtYIt2LiFJov+/EQu5wfeilLURfZwKk2fBIC+CFUwg6ewogb4Ynvxv7++J11+7uMSOkuqu/0t/7rrv4TDt06dtA5oUNfZ5cUH0/H/KX48DkCp+mRI7S5uJ6majXZEm5Nmi7u+gOCSjAewe6Ex++I91MsX3WrgVG5OUffx/QTsLeRhT9ZMAlnED7lcTXNhDCEmJif87CQFucRnrkO9FvDnZG2i9721MLGo9Sf/M7AliwMH7fcVucgvY4AJuESspEjWjQn9YEqhp1cDb/PtNZtRl/v1TJOV4eQUDSWusdw== ambrose-yubikey
|
||||
- name: prevent password login
|
||||
become: yes
|
||||
blockinfile:
|
||||
dest: /etc/ssh/sshd_config
|
||||
block: |
|
||||
PasswordAuthentication no
|
||||
|
Loading…
Reference in New Issue