migrate to git.charlotte.sh
This commit is contained in:
commit
fbd588721e
412 changed files with 13750 additions and 0 deletions
|
@ -0,0 +1,2 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
|
@ -0,0 +1,9 @@
|
|||
[apache]
|
||||
ansible1-charlotte
|
||||
[webmin]
|
||||
ansible2-charlotte
|
||||
[windows]
|
||||
mgmt01-charlotte
|
||||
wks01-charlotte
|
||||
[windows:vars]
|
||||
ansible_shell_type=powershell
|
|
@ -0,0 +1,85 @@
|
|||
- name: Rocky Linux Security Configuration
|
||||
hosts: ansible1-charlotte
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
tasks:
|
||||
# Create security admin group first
|
||||
- name: Create security admin group
|
||||
group:
|
||||
name: secadmin
|
||||
state: present
|
||||
tags: fs_perms
|
||||
|
||||
# ============================================================
|
||||
# SYSTEM ADMINISTRATION ELEMENT: File System Permissions
|
||||
# ============================================================
|
||||
# Create parent directory first
|
||||
- name: Create data directory
|
||||
file:
|
||||
path: /data
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
tags: fs_perms
|
||||
|
||||
- name: Create secure data directory
|
||||
file:
|
||||
path: /data/secure
|
||||
state: directory
|
||||
mode: '0750'
|
||||
owner: root
|
||||
group: secadmin
|
||||
tags: fs_perms
|
||||
|
||||
- name: Set secure permissions on sensitive files
|
||||
file:
|
||||
path: "{{ item.path }}"
|
||||
mode: "{{ item.mode }}"
|
||||
owner: "{{ item.owner }}"
|
||||
group: "{{ item.group }}"
|
||||
with_items:
|
||||
- { path: '/etc/passwd', mode: '0644', owner: 'root', group: 'root' }
|
||||
- { path: '/etc/shadow', mode: '0400', owner: 'root', group: 'root' }
|
||||
- { path: '/etc/ssh/sshd_config', mode: '0600', owner: 'root', group: 'root' }
|
||||
tags: fs_perms
|
||||
|
||||
# ============================================================
|
||||
# SYSTEM HARDENING ELEMENT: Firewall Configuration
|
||||
# ============================================================
|
||||
- name: Ensure firewalld is installed
|
||||
dnf:
|
||||
name: firewalld
|
||||
state: present
|
||||
tags: firewall
|
||||
|
||||
- name: Enable and start firewalld
|
||||
service:
|
||||
name: firewalld
|
||||
state: started
|
||||
enabled: yes
|
||||
tags: firewall
|
||||
|
||||
- name: Allow necessary services
|
||||
firewalld:
|
||||
service: "{{ item }}"
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
with_items:
|
||||
- ssh
|
||||
- http
|
||||
- https
|
||||
tags: firewall
|
||||
|
||||
- name: Block all other ports
|
||||
firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: yes
|
||||
state: disabled
|
||||
immediate: yes
|
||||
with_items:
|
||||
- 21/tcp
|
||||
- 23/tcp
|
||||
- 25/tcp
|
||||
tags: firewall
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
- name: Windows Security Configuration
|
||||
hosts: windows
|
||||
gather_facts: yes
|
||||
tasks:
|
||||
# ============================================================
|
||||
# SYSTEM ADMINISTRATION ELEMENT: Shared Folder Management
|
||||
# ============================================================
|
||||
- name: Create secure shared folder
|
||||
win_file:
|
||||
path: C:\SecureShare
|
||||
state: directory
|
||||
tags: file_mgmt
|
||||
|
||||
- name: Share the secure folder
|
||||
win_share:
|
||||
name: SecureData
|
||||
path: C:\SecureShare
|
||||
description: "Secure data repository"
|
||||
list: yes
|
||||
full: Administrators
|
||||
read: "Domain Users"
|
||||
deny: "Everyone"
|
||||
tags: file_mgmt
|
||||
|
||||
- name: Set NTFS permissions on secure folder
|
||||
win_acl:
|
||||
path: C:\SecureShare
|
||||
user: Administrators
|
||||
rights: FullControl
|
||||
type: allow
|
||||
state: present
|
||||
inheritance_flags: "ContainerInherit,ObjectInherit"
|
||||
tags: ntfs_perms
|
||||
|
||||
- name: Add read permissions for authenticated users
|
||||
win_acl:
|
||||
path: C:\SecureShare
|
||||
user: "Authenticated Users"
|
||||
rights: ReadAndExecute
|
||||
type: allow
|
||||
state: present
|
||||
inheritance_flags: "ContainerInherit,ObjectInherit"
|
||||
tags: ntfs_perms
|
||||
|
||||
# ============================================================
|
||||
# SYSTEM HARDENING ELEMENT: Disable Unnecessary Services
|
||||
# ============================================================
|
||||
- name: Check for service existence
|
||||
win_shell: Get-Service -Name "{{ item }}" -ErrorAction SilentlyContinue
|
||||
register: service_check
|
||||
with_items:
|
||||
- XblGameSave # Xbox Game Saving Service
|
||||
- XboxNetApiSvc # Xbox Live Networking Service
|
||||
- DiagTrack # Connected User Experiences and Telemetry
|
||||
- dmwappushservice # WAP Push Message Routing Service
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
tags: hardening
|
||||
|
||||
- name: Disable unnecessary services if they exist
|
||||
win_service:
|
||||
name: "{{ item.item }}"
|
||||
state: stopped
|
||||
start_mode: disabled
|
||||
with_items: "{{ service_check.results }}"
|
||||
when: item.rc == 0
|
||||
tags: hardening
|
||||
|
||||
- name: Report on services not found
|
||||
debug:
|
||||
msg: "Service {{ item.item }} not found on {{ inventory_hostname }}"
|
||||
with_items: "{{ service_check.results }}"
|
||||
when: item.rc != 0
|
||||
tags: hardening
|
||||
|
||||
# ============================================================
|
||||
# AD DS GPO ELEMENT 1: Password Policy
|
||||
# ============================================================
|
||||
- name: Configure password policy
|
||||
win_security_policy:
|
||||
section: System Access
|
||||
key: "{{ item.key }}"
|
||||
value: "{{ item.value }}"
|
||||
with_items:
|
||||
- { key: PasswordComplexity, value: 1 } # Enable password complexity
|
||||
- { key: MinimumPasswordLength, value: 12 } # 12 character minimum
|
||||
- { key: PasswordHistorySize, value: 24 } # Remember 24 passwords
|
||||
when: inventory_hostname in ['wks01-charlotte', 'mgmt01-charlotte']
|
||||
tags: gpo_password
|
||||
|
||||
# ============================================================
|
||||
# AD DS GPO ELEMENT 2: Account Lockout Policy
|
||||
# ============================================================
|
||||
- name: Configure account lockout policy
|
||||
win_security_policy:
|
||||
section: System Access
|
||||
key: "{{ item.key }}"
|
||||
value: "{{ item.value }}"
|
||||
with_items:
|
||||
- { key: LockoutBadCount, value: 5 } # 5 failed attempts
|
||||
- { key: ResetLockoutCount, value: 30 } # Reset counter after 30 minutes
|
||||
- { key: LockoutDuration, value: 30 } # Lock for 30 minutes
|
||||
when: inventory_hostname in ['wks01-charlotte', 'mgmt01-charlotte']
|
||||
tags: gpo_lockout
|
|
@ -0,0 +1,39 @@
|
|||
- name: apache sys265
|
||||
hosts: apache
|
||||
become: true # Run all tasks with sudo/root privileges
|
||||
vars:
|
||||
install_utilities: false
|
||||
firewalld_enable: true
|
||||
ansible_os_family: RedHat
|
||||
ansible_distribution: CentOS # required because role searches for Rocky config files
|
||||
roles:
|
||||
- geerlingguy.apache # apply the apache installation role
|
||||
|
||||
handlers: # will run when a task has notify:name parameter
|
||||
- name: reload firewall # runs after adding firewall rule
|
||||
command: firewall-cmd --reload
|
||||
|
||||
tasks:
|
||||
# open port 443 in firewall for apache web interface
|
||||
- name: add firewall rule
|
||||
firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
immediate: true
|
||||
state: enabled
|
||||
loop:
|
||||
- 80/tcp
|
||||
- 443/tcp
|
||||
notify: reload firewall
|
||||
|
||||
- name: install apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: present # will only install if not already
|
||||
|
||||
- name: enable and start apache service
|
||||
systemd:
|
||||
name: httpd
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: yes # reload systemd to recognize new service
|
|
@ -0,0 +1,3 @@
|
|||
skip_list:
|
||||
- 'yaml'
|
||||
- 'role-name'
|
4
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/FUNDING.yml
vendored
Normal file
4
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
# These are supported funding model platforms
|
||||
---
|
||||
github: geerlingguy
|
||||
patreon: geerlingguy
|
67
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/ci.yml
vendored
Normal file
67
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
name: CI
|
||||
'on':
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 5 * * 0"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'geerlingguy.apache'
|
||||
|
||||
jobs:
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the codebase.
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'geerlingguy.apache'
|
||||
|
||||
- name: Set up Python 3.
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Install test dependencies.
|
||||
run: pip3 install yamllint
|
||||
|
||||
- name: Lint code.
|
||||
run: |
|
||||
yamllint .
|
||||
|
||||
molecule:
|
||||
name: Molecule
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
distro:
|
||||
- rockylinux8
|
||||
- ubuntu2004
|
||||
- debian10
|
||||
|
||||
steps:
|
||||
- name: Check out the codebase.
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'geerlingguy.apache'
|
||||
|
||||
- name: Set up Python 3.
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Install test dependencies.
|
||||
run: pip3 install ansible molecule molecule-plugins[docker] docker
|
||||
|
||||
- name: Run Molecule tests.
|
||||
run: molecule test
|
||||
env:
|
||||
PY_COLORS: '1'
|
||||
ANSIBLE_FORCE_COLOR: '1'
|
||||
MOLECULE_DISTRO: ${{ matrix.distro }}
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
# This workflow requires a GALAXY_API_KEY secret present in the GitHub
|
||||
# repository or organization.
|
||||
#
|
||||
# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy
|
||||
# See: https://github.com/ansible/galaxy/issues/46
|
||||
|
||||
name: Release
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'geerlingguy.apache'
|
||||
|
||||
jobs:
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the codebase.
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'geerlingguy.apache'
|
||||
|
||||
- name: Set up Python 3.
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Install Ansible.
|
||||
run: pip3 install ansible-core
|
||||
|
||||
- name: Trigger a new import on Galaxy.
|
||||
run: >-
|
||||
ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }}
|
||||
$(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2)
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
name: Close inactive issues
|
||||
'on':
|
||||
schedule:
|
||||
- cron: "55 18 * * 1" # semi-random time
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
days-before-stale: 120
|
||||
days-before-close: 60
|
||||
exempt-issue-labels: bug,pinned,security,planned
|
||||
exempt-pr-labels: bug,pinned,security,planned
|
||||
stale-issue-label: "stale"
|
||||
stale-pr-label: "stale"
|
||||
stale-issue-message: |
|
||||
This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!
|
||||
|
||||
Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale.
|
||||
close-issue-message: |
|
||||
This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details.
|
||||
stale-pr-message: |
|
||||
This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!
|
||||
|
||||
Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale.
|
||||
close-pr-message: |
|
||||
This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details.
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
5
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.gitignore
vendored
Normal file
5
sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
*.retry
|
||||
*/__pycache__
|
||||
*.pyc
|
||||
.cache
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
line-length:
|
||||
max: 120
|
||||
level: warning
|
||||
|
||||
ignore: |
|
||||
.github/workflows/stale.yml
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Jeff Geerling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,208 @@
|
|||
# Ansible Role: Apache 2.x
|
||||
|
||||
[](https://github.com/geerlingguy/ansible-role-apache/actions?query=workflow%3ACI)
|
||||
|
||||
An Ansible Role that installs Apache 2.x on RHEL/CentOS, Debian/Ubuntu, SLES and Solaris.
|
||||
|
||||
## Requirements
|
||||
|
||||
If you are using SSL/TLS, you will need to provide your own certificate and key files. You can generate a self-signed certificate with a command like `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.key -out example.crt`.
|
||||
|
||||
If you are using Apache with PHP, I recommend using the `geerlingguy.php` role to install PHP, and you can either use mod_php (by adding the proper package, e.g. `libapache2-mod-php5` for Ubuntu, to `php_packages`), or by also using `geerlingguy.apache-php-fpm` to connect Apache to PHP via FPM. See that role's README for more info.
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `defaults/main.yml`):
|
||||
|
||||
```yaml
|
||||
apache_enablerepo: ""
|
||||
```
|
||||
|
||||
The repository to use when installing Apache (only used on RHEL/CentOS systems). If you'd like later versions of Apache than are available in the OS's core repositories, use a repository like EPEL (which can be installed with the `geerlingguy.repo-epel` role).
|
||||
|
||||
```yaml
|
||||
apache_listen_ip: "*"
|
||||
apache_listen_port: 80
|
||||
apache_listen_port_ssl: 443
|
||||
```
|
||||
|
||||
The IP address and ports on which apache should be listening. Useful if you have another service (like a reverse proxy) listening on port 80 or 443 and need to change the defaults.
|
||||
|
||||
```yaml
|
||||
apache_create_vhosts: true
|
||||
apache_vhosts_filename: "vhosts.conf"
|
||||
apache_vhosts_template: "vhosts.conf.j2"
|
||||
```
|
||||
|
||||
If set to true, a vhosts file, managed by this role's variables (see below), will be created and placed in the Apache configuration folder. If set to false, you can place your own vhosts file into Apache's configuration folder and skip the convenient (but more basic) one added by this role. You can also override the template used and set a path to your own template, if you need to further customize the layout of your VirtualHosts.
|
||||
|
||||
```yaml
|
||||
apache_remove_default_vhost: false
|
||||
```
|
||||
|
||||
On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. Set this to `true` to remove that default virtualhost configuration file.
|
||||
|
||||
```yaml
|
||||
apache_global_vhost_settings: |
|
||||
DirectoryIndex index.php index.html
|
||||
# Add other global settings on subsequent lines.
|
||||
```
|
||||
|
||||
You can add or override global Apache configuration settings in the role-provided vhosts file (assuming `apache_create_vhosts` is true) using this variable. By default it only sets the DirectoryIndex configuration.
|
||||
|
||||
```yaml
|
||||
apache_vhosts:
|
||||
# Additional optional properties: 'serveradmin, serveralias, extra_parameters'.
|
||||
- servername: "local.dev"
|
||||
documentroot: "/var/www/html"
|
||||
```
|
||||
|
||||
Add a set of properties per virtualhost, including `servername` (required), `documentroot` (required), `allow_override` (optional: defaults to the value of `apache_allow_override`), `options` (optional: defaults to the value of `apache_options`), `serveradmin` (optional), `serveralias` (optional) and `extra_parameters` (optional: you can add whatever additional configuration lines you'd like in here).
|
||||
|
||||
Here's an example using `extra_parameters` to add a RewriteRule to redirect all requests to the `www.` site:
|
||||
|
||||
```yaml
|
||||
- servername: "www.local.dev"
|
||||
serveralias: "local.dev"
|
||||
documentroot: "/var/www/html"
|
||||
extra_parameters: |
|
||||
RewriteCond %{HTTP_HOST} !^www\. [NC]
|
||||
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
||||
```
|
||||
|
||||
The `|` denotes a multiline scalar block in YAML, so newlines are preserved in the resulting configuration file output.
|
||||
|
||||
```yaml
|
||||
apache_vhosts_ssl: []
|
||||
```
|
||||
|
||||
No SSL vhosts are configured by default, but you can add them using the same pattern as `apache_vhosts`, with a few additional directives, like the following example:
|
||||
|
||||
```yaml
|
||||
apache_vhosts_ssl:
|
||||
- servername: "local.dev"
|
||||
documentroot: "/var/www/html"
|
||||
certificate_file: "/home/vagrant/example.crt"
|
||||
certificate_key_file: "/home/vagrant/example.key"
|
||||
certificate_chain_file: "/path/to/certificate_chain.crt"
|
||||
extra_parameters: |
|
||||
RewriteCond %{HTTP_HOST} !^www\. [NC]
|
||||
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
||||
```
|
||||
|
||||
Other SSL directives can be managed with other SSL-related role variables.
|
||||
|
||||
```yaml
|
||||
apache_ssl_no_log: true
|
||||
```
|
||||
|
||||
Whether to print SSL-related task output to the console when running the playbook.
|
||||
|
||||
```yaml
|
||||
apache_ssl_protocol: "All -SSLv2 -SSLv3"
|
||||
apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH"
|
||||
```
|
||||
|
||||
The SSL protocols and cipher suites that are used/allowed when clients make secure connections to your server. These are secure/sane defaults, but for maximum security, performand, and/or compatibility, you may need to adjust these settings.
|
||||
|
||||
```yaml
|
||||
apache_allow_override: "All"
|
||||
apache_options: "-Indexes +FollowSymLinks"
|
||||
```
|
||||
|
||||
The default values for the `AllowOverride` and `Options` directives for the `documentroot` directory of each vhost. A vhost can overwrite these values by specifying `allow_override` or `options`.
|
||||
|
||||
```yaml
|
||||
apache_mods_enabled:
|
||||
- rewrite
|
||||
- ssl
|
||||
apache_mods_disabled: []
|
||||
```
|
||||
|
||||
Which Apache mods to enable or disable (these will be symlinked into the appropriate location). See the `mods-available` directory inside the apache configuration directory (`/etc/apache2/mods-available` on Debian/Ubuntu) for all the available mods.
|
||||
|
||||
```yaml
|
||||
apache_packages:
|
||||
- [platform-specific]
|
||||
```
|
||||
|
||||
The list of packages to be installed. This defaults to a set of platform-specific packages for RedHat or Debian-based systems (see `vars/RedHat.yml` and `vars/Debian.yml` for the default values).
|
||||
|
||||
```yaml
|
||||
apache_state: started
|
||||
```
|
||||
|
||||
Set initial Apache daemon state to be enforced when this role is run. This should generally remain `started`, but you can set it to `stopped` if you need to fix the Apache config during a playbook run or otherwise would not like Apache started at the time this role is run.
|
||||
|
||||
```yaml
|
||||
apache_enabled: yes
|
||||
```
|
||||
|
||||
Set the Apache service boot time status. This should generally remain `yes`, but you can set it to `no` if you need to run Ansible while leaving the service disabled.
|
||||
|
||||
```yaml
|
||||
apache_packages_state: present
|
||||
```
|
||||
|
||||
If you have enabled any additional repositories such as _ondrej/apache2_, [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel), or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to upgrade versions. You can set this to `latest` (combined with `apache_enablerepo` on RHEL) and can directly upgrade to a different Apache version from a different repo (instead of uninstalling and reinstalling Apache).
|
||||
|
||||
```yaml
|
||||
apache_ignore_missing_ssl_certificate: true
|
||||
```
|
||||
|
||||
If you would like to only create SSL vhosts when the vhost certificate is present (e.g. when using Let’s Encrypt), set `apache_ignore_missing_ssl_certificate` to `false`. When doing this, you might need to run your playbook more than once so all the vhosts are configured (if another part of the playbook generates the SSL certificates).
|
||||
|
||||
## .htaccess-based Basic Authorization
|
||||
|
||||
If you require Basic Auth support, you can add it either through a custom template, or by adding `extra_parameters` to a VirtualHost configuration, like so:
|
||||
|
||||
```yaml
|
||||
extra_parameters: |
|
||||
<Directory "/var/www/password-protected-directory">
|
||||
Require valid-user
|
||||
AuthType Basic
|
||||
AuthName "Please authenticate"
|
||||
AuthUserFile /var/www/password-protected-directory/.htpasswd
|
||||
</Directory>
|
||||
```
|
||||
|
||||
To password protect everything within a VirtualHost directive, use the `Location` block instead of `Directory`:
|
||||
|
||||
```
|
||||
<Location "/">
|
||||
Require valid-user
|
||||
....
|
||||
</Location>
|
||||
```
|
||||
|
||||
You would need to generate/upload your own `.htpasswd` file in your own playbook. There may be other roles that support this functionality in a more integrated way.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
```yaml
|
||||
- hosts: webservers
|
||||
vars_files:
|
||||
- vars/main.yml
|
||||
roles:
|
||||
- { role: geerlingguy.apache }
|
||||
```
|
||||
|
||||
*Inside `vars/main.yml`*:
|
||||
|
||||
```yaml
|
||||
apache_listen_port: 8080
|
||||
apache_vhosts:
|
||||
- {servername: "example.com", documentroot: "/var/www/vhosts/example_com"}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT / BSD
|
||||
|
||||
## Author Information
|
||||
|
||||
This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
apache_enablerepo: ""
|
||||
|
||||
apache_listen_ip: "*"
|
||||
apache_listen_port: 80
|
||||
apache_listen_port_ssl: 443
|
||||
|
||||
apache_create_vhosts: true
|
||||
apache_vhosts_filename: "vhosts.conf"
|
||||
apache_vhosts_template: "vhosts.conf.j2"
|
||||
|
||||
# On Debian/Ubuntu, a default virtualhost is included in Apache's configuration.
|
||||
# Set this to `true` to remove that default.
|
||||
apache_remove_default_vhost: false
|
||||
|
||||
apache_global_vhost_settings: |
|
||||
DirectoryIndex index.php index.html
|
||||
|
||||
apache_vhosts:
|
||||
# Additional properties:
|
||||
# 'serveradmin, serveralias, allow_override, options, extra_parameters'.
|
||||
- servername: "local.dev"
|
||||
documentroot: "/var/www/html"
|
||||
|
||||
apache_allow_override: "All"
|
||||
apache_options: "-Indexes +FollowSymLinks"
|
||||
|
||||
apache_vhosts_ssl: []
|
||||
# Additional properties:
|
||||
# 'serveradmin, serveralias, allow_override, options, extra_parameters'.
|
||||
# - servername: "local.dev",
|
||||
# documentroot: "/var/www/html",
|
||||
# certificate_file: "/path/to/certificate.crt",
|
||||
# certificate_key_file: "/path/to/certificate.key",
|
||||
# # Optional.
|
||||
# certificate_chain_file: "/path/to/certificate_chain.crt"
|
||||
|
||||
apache_ignore_missing_ssl_certificate: true
|
||||
|
||||
apache_ssl_no_log: true
|
||||
apache_ssl_protocol: "All -SSLv2 -SSLv3"
|
||||
apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH"
|
||||
|
||||
# Only used on Debian/Ubuntu/Redhat.
|
||||
apache_mods_enabled:
|
||||
- rewrite
|
||||
- ssl
|
||||
apache_mods_disabled: []
|
||||
|
||||
# Set initial apache state. Recommended values: `started` or `stopped`
|
||||
apache_state: started
|
||||
|
||||
# Set initial apache service status. Recommended values: `true` or `false`
|
||||
apache_enabled: true
|
||||
|
||||
# Set apache state when configuration changes are made. Recommended values:
|
||||
# `restarted` or `reloaded`
|
||||
apache_restart_state: restarted
|
||||
|
||||
# Apache package state; use `present` to make sure it's installed, or `latest`
|
||||
# if you want to upgrade or switch versions using a new repo.
|
||||
apache_packages_state: present
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: restart apache
|
||||
service:
|
||||
name: "{{ apache_service }}"
|
||||
state: "{{ apache_restart_state }}"
|
|
@ -0,0 +1,2 @@
|
|||
install_date: Sun Feb 23 19:19:22 2025
|
||||
version: 4.0.0
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
role_name: apache
|
||||
author: geerlingguy
|
||||
description: Apache 2.x for Linux.
|
||||
company: "Midwestern Mac, LLC"
|
||||
license: "license (BSD, MIT)"
|
||||
min_ansible_version: 2.10
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- all
|
||||
- name: Amazon
|
||||
versions:
|
||||
- all
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- trusty
|
||||
- xenial
|
||||
- bionic
|
||||
- name: Solaris
|
||||
versions:
|
||||
- 11.3
|
||||
galaxy_tags:
|
||||
- web
|
||||
- apache
|
||||
- webserver
|
||||
- html
|
||||
- httpd
|
||||
|
||||
allow_duplicates: true
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
apache_listen_port_ssl: 443
|
||||
apache_create_vhosts: true
|
||||
apache_vhosts_filename: "vhosts.conf"
|
||||
apache_vhosts:
|
||||
- servername: "example.com"
|
||||
documentroot: "/var/www/vhosts/example_com"
|
||||
|
||||
pre_tasks:
|
||||
- name: Update apt cache.
|
||||
apt: update_cache=yes cache_valid_time=600
|
||||
when: ansible_os_family == 'Debian'
|
||||
changed_when: false
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.apache
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
role_name_check: 1
|
||||
dependency:
|
||||
name: galaxy
|
||||
options:
|
||||
ignore-errors: true
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: instance
|
||||
image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux8}-ansible:latest"
|
||||
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||
cgroupns_mode: host
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
- name: Configure Apache.
|
||||
lineinfile:
|
||||
dest: "{{ apache_server_root }}/ports.conf"
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
mode: 0644
|
||||
with_items: "{{ apache_ports_configuration_items }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Enable Apache mods.
|
||||
file:
|
||||
src: "{{ apache_server_root }}/mods-available/{{ item }}.load"
|
||||
dest: "{{ apache_server_root }}/mods-enabled/{{ item }}.load"
|
||||
state: link
|
||||
mode: 0644
|
||||
with_items: "{{ apache_mods_enabled }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Disable Apache mods.
|
||||
file:
|
||||
path: "{{ apache_server_root }}/mods-enabled/{{ item }}.load"
|
||||
state: absent
|
||||
with_items: "{{ apache_mods_disabled }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Check whether certificates defined in vhosts exist.
|
||||
stat: "path={{ item.certificate_file }}"
|
||||
register: apache_ssl_certificates
|
||||
with_items: "{{ apache_vhosts_ssl }}"
|
||||
no_log: "{{ apache_ssl_no_log }}"
|
||||
|
||||
- name: Add apache vhosts configuration.
|
||||
template:
|
||||
src: "{{ apache_vhosts_template }}"
|
||||
dest: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: restart apache
|
||||
when: apache_create_vhosts | bool
|
||||
|
||||
- name: Add vhost symlink in sites-enabled.
|
||||
file:
|
||||
src: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}"
|
||||
dest: "{{ apache_conf_path }}/sites-enabled/{{ apache_vhosts_filename }}"
|
||||
state: link
|
||||
mode: 0644
|
||||
force: "{{ ansible_check_mode }}"
|
||||
notify: restart apache
|
||||
when: apache_create_vhosts | bool
|
||||
|
||||
- name: Remove default vhost in sites-enabled.
|
||||
file:
|
||||
path: "{{ apache_conf_path }}/sites-enabled/{{ apache_default_vhost_filename }}"
|
||||
state: absent
|
||||
notify: restart apache
|
||||
when: apache_remove_default_vhost
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
- name: Configure Apache.
|
||||
lineinfile:
|
||||
dest: "{{ apache_server_root }}/conf/{{ apache_daemon }}.conf"
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
mode: 0644
|
||||
with_items: "{{ apache_ports_configuration_items }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Check whether certificates defined in vhosts exist.
|
||||
stat: path={{ item.certificate_file }}
|
||||
register: apache_ssl_certificates
|
||||
with_items: "{{ apache_vhosts_ssl }}"
|
||||
no_log: "{{ apache_ssl_no_log }}"
|
||||
|
||||
- name: Enable Apache mods.
|
||||
copy:
|
||||
dest: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf"
|
||||
content: |
|
||||
LoadModule {{ item }}_module modules/mod_{{ item }}.so
|
||||
mode: 0644
|
||||
with_items: "{{ apache_mods_enabled }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Disable Apache mods
|
||||
file:
|
||||
path: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf"
|
||||
state: absent
|
||||
with_items: "{{ apache_mods_disabled }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Add apache vhosts configuration.
|
||||
template:
|
||||
src: "{{ apache_vhosts_template }}"
|
||||
dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: restart apache
|
||||
when: apache_create_vhosts | bool
|
||||
|
||||
- name: Check if localhost cert exists (RHEL 8 and later).
|
||||
stat:
|
||||
path: /etc/pki/tls/certs/localhost.crt
|
||||
register: localhost_cert
|
||||
when: ansible_distribution_major_version | int >= 8
|
||||
|
||||
- name: Ensure httpd certs are installed (RHEL 8 and later).
|
||||
command: /usr/libexec/httpd-ssl-gencerts
|
||||
when:
|
||||
- ansible_distribution_major_version | int >= 8
|
||||
- not localhost_cert.stat.exists
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
- name: Configure Apache.
|
||||
lineinfile:
|
||||
dest: "{{ apache_server_root }}/{{ apache_daemon }}.conf"
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
mode: 0644
|
||||
with_items: "{{ apache_ports_configuration_items }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Add apache vhosts configuration.
|
||||
template:
|
||||
src: "{{ apache_vhosts_template }}"
|
||||
dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: restart apache
|
||||
when: apache_create_vhosts | bool
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- name: Configure Apache.
|
||||
lineinfile:
|
||||
dest: "{{ apache_server_root }}/listen.conf"
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
mode: 0644
|
||||
with_items: "{{ apache_ports_configuration_items }}"
|
||||
notify: restart apache
|
||||
|
||||
- name: Check whether certificates defined in vhosts exist.
|
||||
stat: path={{ item.certificate_file }}
|
||||
register: apache_ssl_certificates
|
||||
with_items: "{{ apache_vhosts_ssl }}"
|
||||
no_log: "{{ apache_ssl_no_log }}"
|
||||
|
||||
- name: Add apache vhosts configuration.
|
||||
template:
|
||||
src: "{{ apache_vhosts_template }}"
|
||||
dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: restart apache
|
||||
when: apache_create_vhosts | bool
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
# Include variables and define needed variables.
|
||||
- name: Include OS-specific variables.
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
|
||||
- name: Include variables for Amazon Linux.
|
||||
include_vars: "AmazonLinux.yml"
|
||||
when:
|
||||
- ansible_distribution == "Amazon"
|
||||
- ansible_distribution_major_version == "NA"
|
||||
|
||||
- name: Define apache_packages.
|
||||
set_fact:
|
||||
apache_packages: "{{ __apache_packages | list }}"
|
||||
when: apache_packages is not defined
|
||||
|
||||
# Setup/install tasks.
|
||||
- include_tasks: "setup-{{ ansible_os_family }}.yml"
|
||||
|
||||
# Figure out what version of Apache is installed.
|
||||
- name: Get installed version of Apache.
|
||||
command: "{{ apache_daemon_path }}{{ apache_daemon }} -v"
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
register: _apache_version
|
||||
|
||||
- name: Create apache_version variable.
|
||||
set_fact:
|
||||
apache_version: "{{ _apache_version.stdout.split()[2].split('/')[1] }}"
|
||||
|
||||
- name: Include Apache 2.2 variables.
|
||||
include_vars: apache-22.yml
|
||||
when: "apache_version.split('.')[1] == '2'"
|
||||
|
||||
- name: Include Apache 2.4 variables.
|
||||
include_vars: apache-24.yml
|
||||
when: "apache_version.split('.')[1] == '4'"
|
||||
|
||||
# Configure Apache.
|
||||
- name: Configure Apache.
|
||||
include_tasks: "configure-{{ ansible_os_family }}.yml"
|
||||
|
||||
- name: Ensure Apache has selected state and enabled on boot.
|
||||
service:
|
||||
name: "{{ apache_service }}"
|
||||
state: "{{ apache_state }}"
|
||||
enabled: "{{ apache_enabled }}"
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- name: Update apt cache.
|
||||
apt: update_cache=yes cache_valid_time=3600
|
||||
|
||||
- name: Ensure Apache is installed on Debian.
|
||||
apt: "name={{ apache_packages }} state={{ apache_packages_state }}"
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- name: Ensure Apache is installed on RHEL.
|
||||
package:
|
||||
name: "{{ apache_packages }}"
|
||||
state: "{{ apache_packages_state }}"
|
||||
enablerepo: "{{ apache_enablerepo | default(omit, true) }}"
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: Ensure Apache is installed on Solaris.
|
||||
pkg5:
|
||||
name: "{{ apache_packages }}"
|
||||
state: "{{ apache_packages_state }}"
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: Ensure Apache is installed on Suse.
|
||||
zypper:
|
||||
name: "{{ apache_packages }}"
|
||||
state: "{{ apache_packages_state }}"
|
|
@ -0,0 +1,82 @@
|
|||
{{ apache_global_vhost_settings }}
|
||||
|
||||
{# Set up VirtualHosts #}
|
||||
{% for vhost in apache_vhosts %}
|
||||
<VirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}>
|
||||
ServerName {{ vhost.servername }}
|
||||
{% if vhost.serveralias is defined %}
|
||||
ServerAlias {{ vhost.serveralias }}
|
||||
{% endif %}
|
||||
{% if vhost.documentroot is defined %}
|
||||
DocumentRoot "{{ vhost.documentroot }}"
|
||||
{% endif %}
|
||||
|
||||
{% if vhost.serveradmin is defined %}
|
||||
ServerAdmin {{ vhost.serveradmin }}
|
||||
{% endif %}
|
||||
{% if vhost.documentroot is defined %}
|
||||
<Directory "{{ vhost.documentroot }}">
|
||||
AllowOverride {{ vhost.allow_override | default(apache_allow_override) }}
|
||||
Options {{ vhost.options | default(apache_options) }}
|
||||
{% if apache_vhosts_version == "2.2" %}
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
{% else %}
|
||||
Require all granted
|
||||
{% endif %}
|
||||
</Directory>
|
||||
{% endif %}
|
||||
{% if vhost.extra_parameters is defined %}
|
||||
{{ vhost.extra_parameters | indent(width=2, first=True) }}
|
||||
{% endif %}
|
||||
</VirtualHost>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{# Set up SSL VirtualHosts #}
|
||||
{% for vhost in apache_vhosts_ssl %}
|
||||
{% if apache_ignore_missing_ssl_certificate or apache_ssl_certificates.results[loop.index0].stat.exists %}
|
||||
<VirtualHost {{ apache_listen_ip }}:{{ apache_listen_port_ssl }}>
|
||||
ServerName {{ vhost.servername }}
|
||||
{% if vhost.serveralias is defined %}
|
||||
ServerAlias {{ vhost.serveralias }}
|
||||
{% endif %}
|
||||
{% if vhost.documentroot is defined %}
|
||||
DocumentRoot "{{ vhost.documentroot }}"
|
||||
{% endif %}
|
||||
|
||||
SSLEngine on
|
||||
SSLCipherSuite {{ apache_ssl_cipher_suite }}
|
||||
SSLProtocol {{ apache_ssl_protocol }}
|
||||
SSLHonorCipherOrder On
|
||||
{% if apache_vhosts_version == "2.4" %}
|
||||
SSLCompression off
|
||||
{% endif %}
|
||||
SSLCertificateFile {{ vhost.certificate_file }}
|
||||
SSLCertificateKeyFile {{ vhost.certificate_key_file }}
|
||||
{% if vhost.certificate_chain_file is defined %}
|
||||
SSLCertificateChainFile {{ vhost.certificate_chain_file }}
|
||||
{% endif %}
|
||||
|
||||
{% if vhost.serveradmin is defined %}
|
||||
ServerAdmin {{ vhost.serveradmin }}
|
||||
{% endif %}
|
||||
{% if vhost.documentroot is defined %}
|
||||
<Directory "{{ vhost.documentroot }}">
|
||||
AllowOverride {{ vhost.allow_override | default(apache_allow_override) }}
|
||||
Options {{ vhost.options | default(apache_options) }}
|
||||
{% if apache_vhosts_version == "2.2" %}
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
{% else %}
|
||||
Require all granted
|
||||
{% endif %}
|
||||
</Directory>
|
||||
{% endif %}
|
||||
{% if vhost.extra_parameters is defined %}
|
||||
{{ vhost.extra_parameters | indent(width=2, first=True) }}
|
||||
{% endif %}
|
||||
</VirtualHost>
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
apache_service: httpd
|
||||
apache_daemon: httpd
|
||||
apache_daemon_path: /usr/sbin/
|
||||
apache_server_root: /etc/httpd
|
||||
apache_conf_path: /etc/httpd/conf.d
|
||||
|
||||
apache_vhosts_version: "2.4"
|
||||
|
||||
__apache_packages:
|
||||
- httpd24
|
||||
- httpd24-devel
|
||||
- mod24_ssl
|
||||
- openssh
|
||||
|
||||
apache_ports_configuration_items:
|
||||
- regexp: "^Listen "
|
||||
line: "Listen {{ apache_listen_port }}"
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
apache_service: apache2
|
||||
apache_daemon: apache2
|
||||
apache_daemon_path: /usr/sbin/
|
||||
apache_server_root: /etc/apache2
|
||||
apache_conf_path: /etc/apache2
|
||||
|
||||
__apache_packages:
|
||||
- apache2
|
||||
- apache2-utils
|
||||
|
||||
apache_ports_configuration_items:
|
||||
- regexp: "^Listen "
|
||||
line: "Listen {{ apache_listen_port }}"
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
apache_service: httpd
|
||||
apache_daemon: httpd
|
||||
apache_daemon_path: /usr/sbin/
|
||||
apache_server_root: /etc/httpd
|
||||
apache_conf_path: /etc/httpd/conf.d
|
||||
|
||||
apache_vhosts_version: "2.2"
|
||||
|
||||
__apache_packages:
|
||||
- httpd
|
||||
- httpd-devel
|
||||
- mod_ssl
|
||||
- openssh
|
||||
|
||||
apache_ports_configuration_items:
|
||||
- regexp: "^Listen "
|
||||
line: "Listen {{ apache_listen_port }}"
|
||||
- regexp: "^#?NameVirtualHost "
|
||||
line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}"
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
apache_service: apache24
|
||||
apache_daemon: httpd
|
||||
apache_daemon_path: /usr/apache2/2.4/bin/
|
||||
apache_server_root: /etc/apache2/2.4/
|
||||
apache_conf_path: /etc/apache2/2.4/conf.d
|
||||
|
||||
apache_vhosts_version: "2.2"
|
||||
|
||||
__apache_packages:
|
||||
- web/server/apache-24
|
||||
- web/server/apache-24/module/apache-ssl
|
||||
- web/server/apache-24/module/apache-security
|
||||
|
||||
apache_ports_configuration_items:
|
||||
- regexp: "^Listen "
|
||||
line: "Listen {{ apache_listen_port }}"
|
||||
- regexp: "^#?NameVirtualHost "
|
||||
line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}"
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
apache_service: apache2
|
||||
apache_daemon: httpd2
|
||||
apache_daemon_path: /usr/sbin/
|
||||
apache_server_root: /etc/apache2
|
||||
apache_conf_path: /etc/apache2/conf.d
|
||||
|
||||
apache_vhosts_version: "2.2"
|
||||
|
||||
__apache_packages:
|
||||
- apache2
|
||||
- openssh
|
||||
|
||||
apache_ports_configuration_items:
|
||||
- regexp: "^Listen "
|
||||
line: "Listen {{ apache_listen_port }}"
|
||||
- regexp: "^#?NameVirtualHost "
|
||||
line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}"
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
apache_vhosts_version: "2.2"
|
||||
apache_default_vhost_filename: 000-default
|
||||
apache_ports_configuration_items:
|
||||
- {
|
||||
regexp: "^Listen ",
|
||||
line: "Listen {{ apache_listen_port }}"
|
||||
}
|
||||
- {
|
||||
regexp: "^#?NameVirtualHost ",
|
||||
line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
apache_vhosts_version: "2.4"
|
||||
apache_default_vhost_filename: 000-default.conf
|
||||
apache_ports_configuration_items:
|
||||
- {
|
||||
regexp: "^Listen ",
|
||||
line: "Listen {{ (apache_listen_ip == '*') | ternary('', apache_listen_ip + ':') }}{{ apache_listen_port }}"
|
||||
}
|
2
sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/.gitignore
vendored
Normal file
2
sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.DS_Store
|
||||
.dropbox
|
|
@ -0,0 +1,26 @@
|
|||
BSD 3-Clause License ("BSD License 2.0", "Revised BSD License", "New BSD License", or "Modified BSD License")
|
||||
|
||||
Copyright (c) 2019, SEMU Consulting
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,66 @@
|
|||
Role Name
|
||||
=========
|
||||
|
||||
## THIS REPO IS NO LONGER BEING ACTIVELY MAINTAINED OR SUPPORTED.
|
||||
|
||||
### IF ANYONE ELSE WANTS TO TAKE ON THE MAINTENANCE AND SUPPORT, FEEL FREE TO FORK IT.
|
||||
|
||||
[Ansible role](https://galaxy.ansible.com/semuadmin/webmin) to deploy Webmin web-based linux administration utility, running as a
|
||||
systemd service.
|
||||
|
||||
Webmin service will be available on https://hostip:10000.
|
||||
|
||||
Default login will be the userid and password of the installer user.
|
||||
|
||||
You may get a browser warning about Webmin's default self-sign SSL certificate.
|
||||
|
||||
System will reboot after installation.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Installation requires sudo privileges.
|
||||
- Systemd for services control.
|
||||
- Firewalld for firewall control (if required).
|
||||
- Python for Ansible provisioning (note that some minimal distributions do not include python out of the box).
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
- `install_utilities`: false. Set to True to install various utility packages used by Webmin management functions (wget, git, ntpdate, sntp, smartmontools).
|
||||
Note that some minimal distributions do not support all these tools out of the box and may require interactive installation.
|
||||
|
||||
- `enable_firewalld`: false. Set to True to open port 10000 via firewalld (assumes firewalld is installed and running).
|
||||
|
||||
- `uninstall_webmin` : false. Set to true to uninstall Webmin.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
None.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
```yaml
|
||||
|
||||
- name: Provision webmin role
|
||||
hosts: all
|
||||
become: true
|
||||
become_user: root
|
||||
|
||||
vars:
|
||||
enable_firewalld: true
|
||||
install_utilities: true
|
||||
|
||||
roles:
|
||||
- semuadmin.webmin
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD 3-Clause
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
# defaults file for webmin
|
||||
|
||||
webmin_dir: /etc/webmin
|
||||
webmin_yum_repo: "http://download.webmin.com/download/yum"
|
||||
webmin_mirrorlist: "http://download.webmin.com/download/yum/mirrorlist"
|
||||
webmin_gpgkey: "http://www.webmin.com/jcameron-key.asc"
|
||||
|
||||
webmin_apt_repo: "deb [signed-by=/etc/apt/trusted.gpg.d/jcameron-key.asc] https://download.webmin.com/download/repository sarge contrib"
|
||||
|
||||
enable_firewalld: false
|
||||
install_utilities: false
|
||||
uninstall_webmin: false
|
||||
|
||||
webmin_disable_reboot: false
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
# handlers file for webmin
|
||||
|
||||
- name: Restart webmin
|
||||
ansible.builtin.systemd:
|
||||
name: webmin
|
||||
state: restarted
|
|
@ -0,0 +1,2 @@
|
|||
install_date: Sat Feb 22 17:36:07 2025
|
||||
version: v1.0.9
|
|
@ -0,0 +1,29 @@
|
|||
galaxy_info:
|
||||
role_name: webmin
|
||||
author: semu
|
||||
description: webmin role
|
||||
company: SEMU Consulting
|
||||
|
||||
license: BSD 3-Clause
|
||||
|
||||
min_ansible_version: "7"
|
||||
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- "9"
|
||||
- "8"
|
||||
- "7"
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "36"
|
||||
- name: Debian
|
||||
versions:
|
||||
- bullseye
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- focal
|
||||
- bionic
|
||||
- jammy
|
||||
galaxy_tags:
|
||||
- webmin
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
# tasks file for webmin #
|
||||
|
||||
- name: Install webmin
|
||||
ansible.builtin.include_tasks: webmin.yml
|
||||
when: not uninstall_webmin
|
||||
|
||||
- name: Uninstall webmin
|
||||
ansible.builtin.include_tasks: uninstall.yml
|
||||
when: uninstall_webmin
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
# tasks file for uninstall webmin #
|
||||
|
||||
- name: Remove Webmin files and directories
|
||||
ansible.builtin.file:
|
||||
path: "/etc/webmin"
|
||||
state: absent
|
||||
|
||||
- name: Disable firewalld service.
|
||||
ansible.posix.firewalld:
|
||||
zone: public
|
||||
service: webmin
|
||||
permanent: true
|
||||
state: disabled
|
||||
immediate: true
|
||||
when: enable_firewalld
|
||||
|
||||
- name: Remove yum repository for Redhat platforms
|
||||
ansible.builtin.yum_repository:
|
||||
name: webmin
|
||||
description: Webmin yum repo
|
||||
baseurl: "{{ webmin_yum_repo }}"
|
||||
mirrorlist: "{{ webmin_mirrorlist }}"
|
||||
state: absent
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: Remove apt repository for Debian platforms
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "{{ webmin_apt_repo }}"
|
||||
state: absent
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Unnstall supporting packages if added
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- wget
|
||||
- git
|
||||
- ntpdate
|
||||
- sntp
|
||||
- smartmontools
|
||||
state: absent
|
||||
when: install_utilities
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
# tasks file for webmin#
|
||||
|
||||
- name: Install firewalld service template.
|
||||
ansible.builtin.template:
|
||||
src: webmin.xml.j2
|
||||
dest: "/etc/firewalld/services/webmin.xml"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
when: enable_firewalld
|
||||
|
||||
- name: Reload firewalld to register new service.
|
||||
ansible.builtin.command: firewall-cmd --reload
|
||||
register: firewall
|
||||
changed_when: "'success' in firewall.stdout"
|
||||
when: enable_firewalld
|
||||
|
||||
- name: Enable firewalld service.
|
||||
ansible.posix.firewalld:
|
||||
zone: public
|
||||
service: webmin
|
||||
permanent: true
|
||||
state: enabled
|
||||
immediate: true
|
||||
when: enable_firewalld
|
||||
|
||||
- name: Add yum repository and gpg key for Redhat platforms.
|
||||
ansible.builtin.yum_repository:
|
||||
name: webmin
|
||||
description: Webmin yum repo
|
||||
baseurl: "{{ webmin_yum_repo }}"
|
||||
mirrorlist: "{{ webmin_mirrorlist }}"
|
||||
gpgkey: "{{ webmin_gpgkey }}"
|
||||
gpgcheck: true
|
||||
state: present
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: Add a gpg key for Debian platforms.
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ webmin_gpgkey }}"
|
||||
dest: /etc/apt/trusted.gpg.d/jcameron-key.asc
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Add apt repository for Debian platforms.
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "{{ webmin_apt_repo }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Install https transport for Debian platforms.
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- apt-transport-https
|
||||
state: present
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Install Webmin.
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- webmin
|
||||
state: present
|
||||
|
||||
- name: Install supporting packages if required.
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- wget
|
||||
- git
|
||||
- ntpdate
|
||||
- sntp
|
||||
- smartmontools
|
||||
state: present
|
||||
when: install_utilities
|
||||
|
||||
- name: Remove old systemd service.
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/webmin.service
|
||||
state: absent
|
||||
|
||||
- name: Enable webmin as systemd service.
|
||||
ansible.builtin.systemd:
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
name: webmin
|
||||
|
||||
- name: Reboot machine.
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 3600
|
||||
when: not webmin_disable_reboot
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>webmin</short>
|
||||
<description>Webmin Web Based Administration</description>
|
||||
<port port="10000" protocol="tcp"/>
|
||||
</service>
|
|
@ -0,0 +1,2 @@
|
|||
localhost
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- name: Test webmin role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- webmin
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
# vars file for webmin
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
- name: webmin sys265
|
||||
hosts: webmin
|
||||
become: true
|
||||
vars:
|
||||
install_utilities: false
|
||||
firewalld_enable: true
|
||||
|
||||
pre_tasks:
|
||||
- name: add webmin repo and GPG key
|
||||
yum_repository:
|
||||
name: webmin
|
||||
description: Webmin Distribution Neutral
|
||||
baseurl: http://download.webmin.com/download/yum
|
||||
enabled: true
|
||||
gpgcheck: true
|
||||
gpgkey: http://www.webmin.com/jcameron-key.asc
|
||||
|
||||
- name: clean and update YUM cache
|
||||
yum:
|
||||
update_cache: yes
|
||||
|
||||
roles:
|
||||
- semuadmin.webmin
|
||||
|
||||
handlers:
|
||||
- name: reload firewall
|
||||
command: firewall-cmd --reload
|
||||
|
||||
tasks:
|
||||
- name: add firewall rule
|
||||
firewalld:
|
||||
port: 10000/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
notify: reload firewall
|
||||
|
||||
- name: install webmin
|
||||
yum:
|
||||
name: webmin
|
||||
state: present
|
||||
|
||||
- name: enable and start webmin service
|
||||
systemd:
|
||||
name: webmin
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: yes
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
- name: install windows applications
|
||||
hosts: windows
|
||||
tasks:
|
||||
- name: install firefox and 7zip
|
||||
win_chocolatey:
|
||||
name:
|
||||
- firefox
|
||||
- 7zip
|
||||
- notepadplusplus
|
||||
state: present
|
|
@ -0,0 +1,14 @@
|
|||
# This is the network config written by 'subiquity'
|
||||
network:
|
||||
ethernets:
|
||||
ens160:
|
||||
dhcp4: no
|
||||
addresses:
|
||||
- 10.0.5.12/24
|
||||
routes:
|
||||
- to: default
|
||||
via: 10.0.5.2
|
||||
nameservers:
|
||||
addresses:
|
||||
- 10.0.5.5
|
||||
version: 2
|
1
sysadmin-ii-sys265/configs/docker-01/README.md
Normal file
1
sysadmin-ii-sys265/configs/docker-01/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
docker-01 configuration
|
142
sysadmin-ii-sys265/configs/docker-01/cloud.cfg
Normal file
142
sysadmin-ii-sys265/configs/docker-01/cloud.cfg
Normal file
|
@ -0,0 +1,142 @@
|
|||
# The top level settings are used as module
|
||||
# and system configuration.
|
||||
# A set of users which may be applied and/or used by various modules
|
||||
# when a 'default' entry is found it will reference the 'default_user'
|
||||
# from the distro configuration specified below
|
||||
users:
|
||||
- default
|
||||
|
||||
|
||||
# If this is set, 'root' will not be able to ssh in and they
|
||||
# will get a message to login instead as the default $user
|
||||
disable_root: true
|
||||
|
||||
# This will cause the set+update hostname module to not operate (if true)
|
||||
preserve_hostname: true
|
||||
hostname: docker01-charlotte
|
||||
fqdn: docker01-charlotte.charlotte.local
|
||||
|
||||
# If you use datasource_list array, keep array items in a single line.
|
||||
# If you use multi line array, ds-identify script won't read array items.
|
||||
# Example datasource config
|
||||
# datasource:
|
||||
# Ec2:
|
||||
# metadata_urls: [ 'blah.com' ]
|
||||
# timeout: 5 # (defaults to 50 seconds)
|
||||
# max_wait: 10 # (defaults to 120 seconds)
|
||||
|
||||
|
||||
|
||||
# The modules that run in the 'init' stage
|
||||
cloud_init_modules:
|
||||
- migrator
|
||||
- seed_random
|
||||
- bootcmd
|
||||
- write-files
|
||||
- growpart
|
||||
- resizefs
|
||||
- disk_setup
|
||||
- mounts
|
||||
- set_hostname
|
||||
- update_hostname
|
||||
- update_etc_hosts
|
||||
- ca-certs
|
||||
- rsyslog
|
||||
- users-groups
|
||||
- ssh
|
||||
|
||||
# The modules that run in the 'config' stage
|
||||
cloud_config_modules:
|
||||
# Emit the cloud config ready event
|
||||
# this can be used by upstart jobs for 'start on cloud-config'.
|
||||
- emit_upstart
|
||||
- snap
|
||||
- ssh-import-id
|
||||
- keyboard
|
||||
- locale
|
||||
- set-passwords
|
||||
- grub-dpkg
|
||||
- apt-pipelining
|
||||
- apt-configure
|
||||
- ubuntu-advantage
|
||||
- ntp
|
||||
- timezone
|
||||
- disable-ec2-metadata
|
||||
- runcmd
|
||||
- byobu
|
||||
|
||||
# The modules that run in the 'final' stage
|
||||
cloud_final_modules:
|
||||
- package-update-upgrade-install
|
||||
- fan
|
||||
- landscape
|
||||
- lxd
|
||||
- ubuntu-drivers
|
||||
- write-files-deferred
|
||||
- puppet
|
||||
- chef
|
||||
- mcollective
|
||||
- salt-minion
|
||||
- reset_rmc
|
||||
- refresh_rmc_and_interface
|
||||
- rightscale_userdata
|
||||
- scripts-vendor
|
||||
- scripts-per-once
|
||||
- scripts-per-boot
|
||||
- scripts-per-instance
|
||||
- scripts-user
|
||||
- ssh-authkey-fingerprints
|
||||
- keys-to-console
|
||||
- install-hotplug
|
||||
- phone-home
|
||||
- final-message
|
||||
- power-state-change
|
||||
|
||||
# System and/or distro specific settings
|
||||
# (not accessible to handlers/transforms)
|
||||
system_info:
|
||||
# This will affect which distro class gets used
|
||||
distro: ubuntu
|
||||
# Default user name + that default users groups (if added/used)
|
||||
default_user:
|
||||
name: ubuntu
|
||||
lock_passwd: True
|
||||
gecos: Ubuntu
|
||||
groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
|
||||
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
||||
shell: /bin/bash
|
||||
network:
|
||||
renderers: ['netplan', 'eni', 'sysconfig']
|
||||
# Automatically discover the best ntp_client
|
||||
ntp_client: auto
|
||||
# Other config here will be given to the distro class and/or path classes
|
||||
paths:
|
||||
cloud_dir: /var/lib/cloud/
|
||||
templates_dir: /etc/cloud/templates/
|
||||
upstart_dir: /etc/init/
|
||||
package_mirrors:
|
||||
- arches: [i386, amd64]
|
||||
failsafe:
|
||||
primary: http://archive.ubuntu.com/ubuntu
|
||||
security: http://security.ubuntu.com/ubuntu
|
||||
search:
|
||||
primary:
|
||||
- http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
|
||||
- http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
|
||||
- http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
|
||||
security: []
|
||||
- arches: [arm64, armel, armhf]
|
||||
failsafe:
|
||||
primary: http://ports.ubuntu.com/ubuntu-ports
|
||||
security: http://ports.ubuntu.com/ubuntu-ports
|
||||
search:
|
||||
primary:
|
||||
- http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
|
||||
- http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
||||
- http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
||||
security: []
|
||||
- arches: [default]
|
||||
failsafe:
|
||||
primary: http://ports.ubuntu.com/ubuntu-ports
|
||||
security: http://ports.ubuntu.com/ubuntu-ports
|
||||
ssh_svcname: ssh
|
9
sysadmin-ii-sys265/configs/docker-01/hosts
Normal file
9
sysadmin-ii-sys265/configs/docker-01/hosts
Normal file
|
@ -0,0 +1,9 @@
|
|||
127.0.0.1 localhost
|
||||
127.0.1.1 docker01-charlotte
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 ip6-localhost ip6-loopback
|
||||
fe00::0 ip6-localnet
|
||||
ff00::0 ip6-mcastprefix
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
1
sysadmin-ii-sys265/configs/mgmt-01/README.md
Normal file
1
sysadmin-ii-sys265/configs/mgmt-01/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
mgmt01-charlotte
|
15
sysadmin-ii-sys265/docker_proj1/Dockerfile
Normal file
15
sysadmin-ii-sys265/docker_proj1/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
|||
# use this version of python
|
||||
FROM python:3.12-slim
|
||||
|
||||
# create a working directory and copy requirements file to it
|
||||
WORKDIR /app
|
||||
COPY app/requirements.txt /app/requirements.txt
|
||||
|
||||
# install dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# copy the rest of the files to working directory
|
||||
COPY app /app
|
||||
|
||||
# run the python script when the container starts
|
||||
CMD ["python", "app.py"]
|
143
sysadmin-ii-sys265/docker_proj1/README.md
Normal file
143
sysadmin-ii-sys265/docker_proj1/README.md
Normal file
|
@ -0,0 +1,143 @@
|
|||
# SYS265 - Mini Docker Project
|
||||
flask web-chat app with docker
|
||||
___
|
||||
|
||||
|
||||
>[!Note]
|
||||
> I've been learning some network programming lately, so most of the python is my own. but I did use AI for the Dockerfile, some of the javascript, and general troubleshooting (netwoking in a Docker container can get confusing)
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
├── docker-chat
|
||||
│ ├── app
|
||||
│ │ ├── app.py
|
||||
│ │ ├── requirements.txt
|
||||
│ │ └── templates
|
||||
│ │ └── index.html
|
||||
│ ├── docker-compose.yml
|
||||
│ └── Dockerfile
|
||||
```
|
||||
|
||||
___
|
||||
## 1. create [app.py](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/app.py)
|
||||
this is the python/flask backend for the web app. it will open a websocket on port 5000 and handle message sent over it.
|
||||
```
|
||||
from flask import Flask, render_template
|
||||
from flask_socketio import SocketIO, send
|
||||
|
||||
# initialize flask and socketio
|
||||
app = Flask(__name__)
|
||||
socketio = SocketIO(app)
|
||||
|
||||
# default page
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# runs when message is received on socket
|
||||
@socketio.on('message')
|
||||
def handle_message(msg):
|
||||
print("message: " + msg)
|
||||
send(msg, broadcast=True)
|
||||
|
||||
# open websocket, listen on port 5000
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True)
|
||||
```
|
||||
|
||||
## 2. create [index.html](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/templates/index.html)
|
||||
this is the html frontend for the web page, as well as some javascript to be a medium between network connections and the frontend webpage
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>sys265 chat</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<ul id="messages"></ul>
|
||||
<input id="message_input" type="text">
|
||||
<button onclick="sendMessage()">send</button>
|
||||
|
||||
<!-- import javascript sockets.io library-->
|
||||
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
// create websocket object
|
||||
const socket = io()
|
||||
|
||||
// update html when a message is sent/received
|
||||
socket.on('message', function(msg) {
|
||||
let li = document.createElement('li');
|
||||
li.textContent = msg;
|
||||
document.getElementById('messages').appendChild(li);
|
||||
});
|
||||
|
||||
// send message on socket when button is clicked
|
||||
function sendMessage() {
|
||||
const message = document.getElementById('message_input').value;
|
||||
socket.send(message);
|
||||
document.getElementById('message_input').value = '';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## 3. create [requirements.txt](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/requirements.txt)
|
||||
this includes necessary dependencies. they will be installed via Dockerfile
|
||||
```
|
||||
Flask==2.2.2
|
||||
flask-socketio==5.3.2
|
||||
werkzeug==2.2.2
|
||||
```
|
||||
|
||||
## 4. create [docker-compose.yml](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/docker-compose.yml)
|
||||
this defines the services to be used. while this could work without the chat-net network, creating an isolated network made setting this up simpley imo, especially since we are already running wordpress.
|
||||
```
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
chat-server:
|
||||
build: .
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
- ./app:/app
|
||||
networks:
|
||||
- chat-net
|
||||
|
||||
networks:
|
||||
chat-net:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
## 5. create [Dockerfile](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/Dockerfile)
|
||||
```
|
||||
# use this version of python
|
||||
FROM python:3.12-slim
|
||||
|
||||
# create a working directory and copy requirements file to it
|
||||
WORKDIR /app
|
||||
COPY app/requirements.txt /app/requirements.txt
|
||||
|
||||
# install dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# copy the rest of the files to working directory
|
||||
COPY app /app
|
||||
|
||||
# run the python script when the container starts
|
||||
CMD ["python", "app.py"]
|
||||
```
|
||||
|
||||
## 6. run docker-compose
|
||||
```
|
||||
cd docker-chat
|
||||
docker-compose up -d
|
||||
```
|
||||

|
21
sysadmin-ii-sys265/docker_proj1/app/app.py
Normal file
21
sysadmin-ii-sys265/docker_proj1/app/app.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from flask import Flask, render_template
|
||||
from flask_socketio import SocketIO, send
|
||||
|
||||
# initialize flask and socketio
|
||||
app = Flask(__name__)
|
||||
socketio = SocketIO(app)
|
||||
|
||||
# default page
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# runs when message is received on socket
|
||||
@socketio.on('message')
|
||||
def handle_message(msg):
|
||||
print("message: " + msg)
|
||||
send(msg, broadcast=True)
|
||||
|
||||
# open websocket, listen on port 5000
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True)
|
3
sysadmin-ii-sys265/docker_proj1/app/requirements.txt
Normal file
3
sysadmin-ii-sys265/docker_proj1/app/requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Flask==2.2.2
|
||||
flask-socketio==5.3.2
|
||||
werkzeug==2.2.2
|
38
sysadmin-ii-sys265/docker_proj1/app/templates/index.html
Normal file
38
sysadmin-ii-sys265/docker_proj1/app/templates/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>sys265 chat</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<ul id="messages"></ul>
|
||||
<input id="message_input" type="text">
|
||||
<button onclick="sendMessage()">send</button>
|
||||
|
||||
<!-- import javascript sockets.io library-->
|
||||
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
// create websocket object
|
||||
const socket = io()
|
||||
|
||||
// update html when a message is sent/received
|
||||
socket.on('message', function(msg) {
|
||||
let li = document.createElement('li');
|
||||
li.textContent = msg;
|
||||
document.getElementById('messages').appendChild(li);
|
||||
});
|
||||
|
||||
// send message on socket when button is clicked
|
||||
function sendMessage() {
|
||||
const message = document.getElementById('message_input').value;
|
||||
socket.send(message);
|
||||
document.getElementById('message_input').value = '';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
15
sysadmin-ii-sys265/docker_proj1/docker-compose.yml
Normal file
15
sysadmin-ii-sys265/docker_proj1/docker-compose.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
chat-server:
|
||||
build: .
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
- ./app:/app
|
||||
networks:
|
||||
- chat-net
|
||||
|
||||
networks:
|
||||
chat-net:
|
||||
driver: bridge
|
51
sysadmin-ii-sys265/labs/lab00-environment-setup.md
Normal file
51
sysadmin-ii-sys265/labs/lab00-environment-setup.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Lab00 - Routing and Windows
|
||||
|
||||
Our goal is to build a realistic server environment consisting of a routed network (LAN and WAN) as well as introduce Server 2019 Desktop and Core and the systems required to manage them.
|
||||
|
||||
## FW01 and WKS01
|
||||
- [use this doc](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab01-environment-setup.md), configuration is exactly the same
|
||||
|
||||
## AD01
|
||||
- (admin password is `password123!`)
|
||||
- `sconfig` \
|
||||

|
||||
|
||||
- Invoke powershell and install Active Directory: `Install-WindowsFeature AD-Domain-Services -IncludeManagementTools` \
|
||||

|
||||
|
||||
- Install the Forest: `Install-ADDSForest -DomainName charlotte.local` \
|
||||

|
||||
|
||||
- You should be in a domain now \
|
||||

|
||||
|
||||
### creating domain users (one user, one admin):
|
||||
- `net user charlotte.croce password123! /ADD /DOMAIN`
|
||||
- `net user charlotte.croce-adm password123! /ADD /DOMAIN`
|
||||
- `net group "Domain Admins" charlotte.croce-adm /ADD /DOMAIN`
|
||||
|
||||
|
||||
## MGMT01
|
||||
MGMT01 is a Server 2019 with GUI. Its job will be to remotely manage any server core systems.
|
||||
password: `password123!` \
|
||||

|
||||
|
||||
to join domain:
|
||||
- `sconfig` -> 1 -> D -> charlotte.local -> Administrator -> type Administrator password in prompt -> restart
|
||||
- login as the charlotte.croce-adm domain user
|
||||
|
||||
adding ad01 to management scope
|
||||
- server manager - add roles and features
|
||||
- add the following features: \
|
||||

|
||||

|
||||
|
||||
- create DNS records: [use this doc](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab02-dns%2Badds-role.md)
|
||||
- note: it's easier to create the reverse lookup zone first, as PTR records will be created automatically when you create a new A record, although you will still have to manually create some PTRs
|
||||

|
||||

|
||||
|
||||
- finally, join wks01 to the domain
|
||||
- before doing so, we must change the DNS server to 10.0.5.5, to recognize charlotte.local
|
||||

|
||||
|
63
sysadmin-ii-sys265/labs/lab01-network-management.md
Normal file
63
sysadmin-ii-sys265/labs/lab01-network-management.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
# lab01- Network Management
|
||||
|
||||
## nmon1-charlotte
|
||||
- setup with hostname, username, networking (10.0.5.11, remember: add `charlotte.local` to search domain)
|
||||
- add record to DNS manager \
|
||||

|
||||
|
||||
```
|
||||
I had trouble reaching the internet on nmon1, then realized fw01 couldn't reach the internet as well.
|
||||
idk what happened but I rebooted fw01 and it worked again
|
||||
```
|
||||
|
||||
## enable SNMP services on pfSense
|
||||
- web dashboard (10.0.5.2)
|
||||
- services -> SNMP \
|
||||
 \
|
||||

|
||||
- restart SNMP service \
|
||||

|
||||
|
||||
|
||||
## Install and Test SNMP Client on nmon01
|
||||
- `sudo yum install net-snmp-utils` \
|
||||

|
||||
|
||||
## Install SNMPD (a SNMP Server) on web01
|
||||
- set up web01 (10.0.5.12, you know the drill by now)
|
||||
- `sudo yum install net-snmp-utils net-snmp`
|
||||
- The default snmp configuration does not suit our purpose. Make a backup copy of /etc/snmp/snmpd.conf and create a new/blank version.
|
||||
- `sudo cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.backup` \
|
||||

|
||||
- allow 161/udp through firewall
|
||||
```
|
||||
sudo firewall-cmd --add-port=161/udp --permanent`
|
||||
sudo firewall-cmd --reload`
|
||||
```
|
||||
- enable/start snmpd
|
||||
```
|
||||
sudo systemctl enable snmpd
|
||||
sudo systemctl start snmpd
|
||||
```
|
||||
|
||||
## install the SNMP Service Feature on AD01 using Server Manager on MGMT
|
||||
## install the SNMP-Tools Remote Administration Feature on MGM01
|
||||
 \
|
||||

|
||||
|
||||
|
||||
## Enable Remote Management on AD01
|
||||
Remote Computer Management does not work immediately for our remote AD01 Server due to firewall restrictions as seen in the error message. \
|
||||
 \
|
||||
You will need to fix this by invoking a remote PowerShell session with AD01 from mgmt01. \
|
||||

|
||||
|
||||
## SNMP Service Security Properties on AD01
|
||||
- Adjust the SNMP service properties on AD01 to add the SYS265 community string and limit queries to those from nmon01. \
|
||||

|
||||
- Restart the SNMP Service on ad01
|
||||
|
||||
|
||||
## Capturing snmp packets nmon01->web01
|
||||
- on web01: `tcpdump -i ens192 port 161 -c10 -AAA`
|
||||
- on nom01: `snmpwalk -Os -c SYS265 -v2c web01-charlotte system`
|
15
sysadmin-ii-sys265/labs/lab02-dhcp.md
Normal file
15
sysadmin-ii-sys265/labs/lab02-dhcp.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# DHCP Lab
|
||||
[reference from SYS255](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md)
|
||||
|
||||
ad01- add roles and features \
|
||||

|
||||
|
||||
DNS Manager
|
||||
Configurations:
|
||||
- Scope: 10.0.5.150 - 10.0.5.175
|
||||
- Subnet mask: /24
|
||||
- Router: 10.0.5.2
|
||||
- DNS: 10.0.5.5
|
||||
|
||||
on wks-01, set IP to acquire automatically \
|
||||

|
181
sysadmin-ii-sys265/labs/lab03-docker.md
Normal file
181
sysadmin-ii-sys265/labs/lab03-docker.md
Normal file
|
@ -0,0 +1,181 @@
|
|||
# Containerization with Docker
|
||||

|
||||
|
||||
## set up docker01 - Ubuntu 20.04 cloud server
|
||||
IP Address: 10.0.5.12 (change web01 address to 10.0.5.20) \
|
||||
Default Gateway: 10.0.5.2 \
|
||||
DNS: 10.0.5.5 \
|
||||

|
||||
|
||||
### changing hostname. it is different on Ubuntu Cloud
|
||||
- in `/etc/cloud/cloud.cfg`:
|
||||
```
|
||||
preserve_hostname: true
|
||||
hostname: docker01-charlotte (add this line under)
|
||||
fqdn: docker01-charlotte.charlotte.local (add this line under)
|
||||
```
|
||||
- change hostname for 127.0.1.1 in `/etc/hosts` file
|
||||
|
||||

|
||||
|
||||
- finally, `sudo hostnamectl hostname docker01-charlotte`
|
||||
- update DNS records on mgmt01 (remember to change web01 record too)
|
||||
|
||||
## docker installation
|
||||
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04
|
||||
|
||||
update and install prerequisite packages, this will let apt use packages over HTTPS
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install apt-transport-https ca-certificates curl software-properties-common
|
||||
```
|
||||
add the GPG key
|
||||
```
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||
```
|
||||
add docker repo to APT sources
|
||||
```
|
||||
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
|
||||
```
|
||||
validate installation is from docker repo. Notice that docker-ce is not installed,
|
||||
but the candidate for installation is from the Docker repository for Ubuntu 20.04 (focal).
|
||||
```
|
||||
apt-cache policy docker-ce | head
|
||||
```
|
||||

|
||||
|
||||
install docker
|
||||
```
|
||||
sudo apt install docker-ce
|
||||
```
|
||||
|
||||
check status
|
||||
```
|
||||
sudo systemctl status docker
|
||||
```
|
||||
|
||||
### executing the docker command without sudo:
|
||||
add user to the docker group, apply the new group membership, and logout/log back in
|
||||
```
|
||||
sudo usermod -aG docker charlotte
|
||||
su - charlotte
|
||||
```
|
||||
|
||||
## using docker
|
||||
### downloading images
|
||||
search for images availabe on Docker Hub
|
||||
```
|
||||
docker search <image-name>
|
||||
```
|
||||
download from Dockuer Hub
|
||||
```
|
||||
docker pull <image-name>
|
||||
```
|
||||
see installed images
|
||||
```
|
||||
docker images
|
||||
```
|
||||
|
||||
|
||||
## docker-compose
|
||||
- https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04
|
||||
> "Docker Compose is a tool that allows you to run multi-container application environments based on definitions set in a YAML file."
|
||||
|
||||
download the 1.29.2 release and save the executable file at /usr/local/bin/docker-compose
|
||||
```
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
```
|
||||
make docker-compose executable:
|
||||
```
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
```
|
||||
verify installation
|
||||
```
|
||||
docker-compose --version
|
||||
```
|
||||
|
||||
The following command pulls down an Arch Linux based docker image, invokes it in a container, and runs /bin/echo "HELLO SYS265 SNOWY DAYS '' before deleting the container.
|
||||
```
|
||||
docker run --rm archlinux:latest /bin/echo "HELLO SYS265 SNOWY DAYS"
|
||||
```
|
||||
|
||||
|
||||
___
|
||||
|
||||
## docker run command syntax (example)
|
||||
- e.g. The following command will pull down the image, application and dependencies associated with a simple python web application. `docker run -d -P training/webapp python app.py`
|
||||
- `docker`: CLI for interacting with docker
|
||||
- `run`: create and start a new container
|
||||
- `-d` (or `--detach`): the container runs in the background.
|
||||
- useful for non-interactive services, like webservers and databases
|
||||
- `-P` (or `--publich-all`): automatically publishes all exposed ports of the container to random host ports.
|
||||
- This allows external access to the services running in the container without having to specify port mappings manually.
|
||||
- `training/webapp`: the docker image from which the container is created
|
||||
- In this case, an image named `webapp` that is located in the `training` repository
|
||||
- `python`: command that will be executed inside the container once it starts
|
||||
- `app.py`: argument passed to the python command
|
||||
- the Python script `app.py` should be executed by the Python interpreter when the container starts.
|
||||
|
||||
|
||||
- `docker run httpd` will automatically set up an apache web server in the container
|
||||
|
||||
### to stop docker process
|
||||
```
|
||||
docker stop <container ID>
|
||||
```
|
||||
|
||||
## dockerized WordPress
|
||||
https://github.com/docker/awesome-compose/tree/master/wordpress-mysql
|
||||
|
||||
- create a directory `docker-wp`
|
||||
- create compose.yml
|
||||
>[!Caution]
|
||||
> Absolutely never use a tab in a docker-compose.yml file
|
||||
|
||||
```
|
||||
services:
|
||||
db:
|
||||
# We use a mariadb image which supports both amd64 & arm64 architecture
|
||||
image: mariadb:10.6.4-focal
|
||||
# If you really want to use MySQL, uncomment the following line
|
||||
#image: mysql:8.0.27
|
||||
command: '--default-authentication-plugin=mysql_native_password'
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
restart: always
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=somewordpress
|
||||
- MYSQL_DATABASE=wordpress
|
||||
- MYSQL_USER=wordpress
|
||||
- MYSQL_PASSWORD=wordpress
|
||||
expose:
|
||||
- 3306
|
||||
- 33060
|
||||
wordpress:
|
||||
image: wordpress:latest
|
||||
ports:
|
||||
- 80:80
|
||||
restart: always
|
||||
environment:
|
||||
- WORDPRESS_DB_HOST=db
|
||||
- WORDPRESS_DB_USER=wordpress
|
||||
- WORDPRESS_DB_PASSWORD=wordpress
|
||||
- WORDPRESS_DB_NAME=wordpress
|
||||
volumes:
|
||||
db_data:
|
||||
```
|
||||
|
||||
- `docker compose up -d`
|
||||
- wait...it's really that easy?
|
||||
- yes
|
||||
|
||||
___
|
||||
|
||||
### showing how containers use the same kernel as the host
|
||||
- example: the following commands will:
|
||||
- Print out the current version of Ubuntu on docker01. `cat /etc/lsb-release`
|
||||
- Print out the current version of docker01's linux kernel. `echo "Current Kernel is: $(uname -a)"`
|
||||
- Invoke a container of the stored Ubuntu image as well as an interactive bash command prompt, and print out the kernel being used by the Ubuntu container. `docker run -it archlinux /bin/uname -a`
|
||||

|
||||
- as you can see, both the docker container(archlinux) and the host(docker01-charlotte) are using the same kernels
|
||||
|
59
sysadmin-ii-sys265/labs/lab04-git-and-linux-ssh.md
Normal file
59
sysadmin-ii-sys265/labs/lab04-git-and-linux-ssh.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Git and Linux SSH
|
||||
|
||||
>[!Note]
|
||||
>This entry is pretty empty because I've already written [this journal Entry for using git/github](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week01/github_setup.md)
|
||||
|
||||
# Automating ssh authentication
|
||||
- generate SSH key pair on your management node (in this case, web-01)
|
||||
- push pubkey to github repo
|
||||
- run the secure-ssh.sh script on remote host to create a new user that has the pubkey in `.../.ssh/authorized_keys`
|
||||
- you can now ssh from web-01 to remote hosts without password!
|
||||
|
||||
___
|
||||
### creating/adding ssh key
|
||||
```
|
||||
ssh-keygen -t rsa -b 4096 -C "sys265"
|
||||
cat ~/.ssh/id_rsa
|
||||
```
|
||||
copy this to github SSH & GPG section
|
||||
- to test: `ssh -T git@github.com`
|
||||
- `git remote -v`
|
||||
- if git is using https. you will have to change it to use ssh
|
||||
- `git remote set-url origin git@github.com:charlottecroce/champlaintechjournals`
|
||||
___
|
||||
before being able to commit, you will have to add the following authentication:
|
||||
- `git config user.email charlotte.croce@mymail.champlain.edu`
|
||||
- `git config user.name charlottecroce`
|
||||
|
||||
## docker-01
|
||||
copying config files to git repo
|
||||
```
|
||||
sudo apt install git
|
||||
git clone https://git.charlotte.sh/lotte/ChamplainTechJournals
|
||||
cd ~/champlaintechjournals/sysadmin-ii-sys265/configs/docker-01
|
||||
sudo cp /etc/hosts .
|
||||
sudo cp /etc/netplan/* .
|
||||
sudo cp /etc/cloud/cloud.cfg .
|
||||
```
|
||||
|
||||
## mgmt-01
|
||||
- install git from web
|
||||
```
|
||||
git clone https://git.charlotte.sh/lotte/ChamplainTechJournals
|
||||
cd ~/champlaintechjournals/sysadmin-ii-sys265/configs/mgmt-01
|
||||
echo $(hostname) > README.md
|
||||
git add .
|
||||
git commit -m "added a readme"
|
||||
git push
|
||||
```
|
||||
- login with token authentication
|
||||
|
||||
# web-01
|
||||
- `sudo yum install git`
|
||||
- create ssh key and connect to git with it (see above section)
|
||||
```
|
||||
mkdir -p linux/public-keys
|
||||
mkdir -p linux/ubuntu
|
||||
mkdir -p linux/centos7
|
||||
```
|
||||
- create [secure-ssh.sh script](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/linux/centos7/secure-ssh.sh)
|
322
sysadmin-ii-sys265/labs/lab05-ansible-automation.md
Normal file
322
sysadmin-ii-sys265/labs/lab05-ansible-automation.md
Normal file
|
@ -0,0 +1,322 @@
|
|||
# Automation with Ansible
|
||||
Demonisioning: web01, nmon-01, docker-01 😢
|
||||
___
|
||||
## New Machines
|
||||
### controller-charlotte - Ubuntu
|
||||
configure with netplan
|
||||
```
|
||||
network:
|
||||
ethernets:
|
||||
ens160:
|
||||
dhcp4: no
|
||||
addresses:
|
||||
- 10.0.5.90/24
|
||||
routes:
|
||||
- to: default
|
||||
via: 10.0.5.2
|
||||
nameservers:
|
||||
addresses:
|
||||
- 10.0.5.5
|
||||
version: 2
|
||||
```
|
||||
#### to reset DNS
|
||||
```
|
||||
dhclient -r
|
||||
dhclient
|
||||
```
|
||||
### ansible1-charlotte - CentOS
|
||||
configure with nmtui
|
||||
- IP: 10.0.5.91
|
||||
- DG: 10.0.5.2
|
||||
- DNS: 10.0.5.5
|
||||
### ansible2-charlotte - CentOS
|
||||
configure with nmtui
|
||||
- IP: 10.0.5.92
|
||||
- DG: 10.0.5.2
|
||||
- DNS: 10.0.5.5
|
||||
|
||||
## Initial Configuration
|
||||
- on all machines, create a sudo account named deployer (use same password across all systems)
|
||||
- install ansible on controller
|
||||
```
|
||||
sudo apt install ansible sshpass python3-paramiko
|
||||
```
|
||||
- Configure sudo access:
|
||||
- create `/etc/sudoers.d/sys265` on all systems
|
||||
- add the following line to allow passwordless sudo for deployer:
|
||||
```
|
||||
deployer ALL=(ALL) NOPASSWD:ALL
|
||||
```
|
||||
|
||||
> [!Note]
|
||||
> Although it is not uncommon to update `/etc/sudoers` directly, it is far easier to script the addition of a file to `/etc/sudoers.d`
|
||||
|
||||
|
||||
## SSH Key Setup
|
||||
As the deployer user on controller:
|
||||
- Create RSA keypair with passphrase:
|
||||
```
|
||||
ssh-keygen -t rsa
|
||||
```
|
||||
- copy pukey to ansible1 and ansible2
|
||||
```
|
||||
ssh-copy-id deployer@ansible1-charlotte
|
||||
ssh-copy-id deployer@ansible2-charlotte
|
||||
```
|
||||
-configure `ssh-agent` to avoid typing passphrase for 4 hours
|
||||
```
|
||||
eval(ssh-agent) # test to see if ssh-agent is running, and if not,run it
|
||||
ssh-add -t 14400
|
||||
```
|
||||
## Ansible Configuration
|
||||
in `deployer@controller:/home/deployer/`
|
||||
- make directory structure
|
||||
```
|
||||
mkdir -p ansible/roles
|
||||
cd ansible/
|
||||
```
|
||||
- create inventory and test conection
|
||||
```
|
||||
echo ansible1-charlotte >> inventory.txt
|
||||
echo ansible2-charlotte >> inventory.txt
|
||||
cat inventory.txt
|
||||
```
|
||||
```
|
||||
ansible all -m ping -i inventory.txt
|
||||
```
|
||||
|
||||
- add webmin tag to `inventory.txt` and test
|
||||
|
||||
```
|
||||
ansible1-charlotte
|
||||
[webmin]
|
||||
ansible2-charlotte
|
||||
```
|
||||
|
||||
```
|
||||
deployer@controller-charlotte:~/ansible$ ansible webmin -m ping -i inventory.txt
|
||||
ansible2-charlotte | SUCCESS => {
|
||||
"ansible_facts": {
|
||||
"discovered_interpreter_python": "/usr/libexec/platform-python"
|
||||
},
|
||||
"changed": false,
|
||||
"ping": "pong"
|
||||
}
|
||||
```
|
||||
|
||||
## webmin installation
|
||||
- install webmin role
|
||||
```
|
||||
ansible-galaxy install semuadmin.webmin -p roles/
|
||||
```
|
||||
- create `webmin.yml` playbook to handle repository setup, installation, and firewall configuration
|
||||
```
|
||||
- name: webmin sys265
|
||||
hosts: webmin
|
||||
become: true # Run all tasks with sudo/root privileges
|
||||
vars:
|
||||
install_utilities: false
|
||||
firewalld_enable: true
|
||||
|
||||
pre_tasks: # before role execution. we need the repo/key before executing webmin installation role
|
||||
- name: add webmin repo and GPG key
|
||||
yum_repository:
|
||||
name: webmin
|
||||
description: Webmin Distribution Neutral
|
||||
baseurl: http://download.webmin.com/download/yum
|
||||
enabled: true
|
||||
gpgcheck: true
|
||||
gpgkey: http://www.webmin.com/jcameron-key.asc
|
||||
|
||||
# update YUM cache to recognize new repository
|
||||
- name: clean and update YUM cache
|
||||
yum:
|
||||
update_cache: yes
|
||||
|
||||
roles:
|
||||
- semuadmin.webmin # apply the webmin installation role
|
||||
|
||||
handlers: # will run when a task has notify:name parameter
|
||||
- name: reload firewall # runs after adding firewall rule
|
||||
command: firewall-cmd --reload
|
||||
|
||||
tasks:
|
||||
# open port 10000 in firewall for webmin web interface
|
||||
- name: add firewall rule
|
||||
firewalld:
|
||||
port: 10000/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
notify: reload firewall
|
||||
|
||||
- name: install webmin
|
||||
yum:
|
||||
name: webmin
|
||||
state: present # will only install if not already
|
||||
|
||||
- name: enable and start webmin service
|
||||
systemd:
|
||||
name: webmin
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: yes # reload systemd to recognize new service
|
||||
```
|
||||
- run playbook
|
||||
```
|
||||
ansible-playbook -i inventory.txt roles/webmin.yml
|
||||
```
|
||||
- change webmin root password
|
||||
```
|
||||
sudo /usr/libexec/webmin/changepass.pl /etc/webmin root newpassword
|
||||
```
|
||||
|
||||
|
||||
## apache isntallation
|
||||
- edit inventory.txt
|
||||
```
|
||||
[apache]
|
||||
ansible1-charlotte
|
||||
[webmin]
|
||||
ansible2-charlotte
|
||||
```
|
||||
- install apache role
|
||||
```
|
||||
ansible-galaxy install geerlingguy.apache -p roles/
|
||||
```
|
||||
- create `apache.yml` file
|
||||
```
|
||||
- name: apache sys265
|
||||
hosts: apache
|
||||
become: true # Run all tasks with sudo/root privileges
|
||||
vars:
|
||||
install_utilities: false
|
||||
firewalld_enable: true
|
||||
ansible_os_family: RedHat
|
||||
ansible_distribution: CentOS # required because role searches for Rocky config files
|
||||
roles:
|
||||
- geerlingguy.apache # apply the apache installation role
|
||||
|
||||
handlers: # will run when a task has notify:name parameter
|
||||
- name: reload firewall # runs after adding firewall rule
|
||||
command: firewall-cmd --reload
|
||||
|
||||
tasks:
|
||||
# open port 443 in firewall for apache web interface
|
||||
- name: add firewall rule
|
||||
firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
immediate: true
|
||||
state: enabled
|
||||
loop:
|
||||
- 80/tcp
|
||||
- 443/tcp
|
||||
notify: reload firewall
|
||||
|
||||
- name: install apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: present # will only install if not already
|
||||
|
||||
- name: enable and start apache service
|
||||
systemd:
|
||||
name: httpd
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: yes # reload systemd to recognize new service
|
||||
|
||||
```
|
||||
- run playbook
|
||||
```
|
||||
ansible-playbook -i inventory.txt roles/webmin.yml
|
||||
```
|
||||
|
||||
# Ansible on Windows
|
||||
## OpenSSH Server Setup
|
||||
|
||||
>[!Caution]
|
||||
> DO NOT INSTALL 32 BIT VERSION
|
||||
|
||||
### Install OpenSSH
|
||||
Run these commands in PowerShell as Administrator:
|
||||
```
|
||||
wget https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.8.1.0p1-Preview/OpenSSH-Win64.zip -O 'C:\Program Files\OpenSSH.zip'
|
||||
Expand-Archive -Path 'C:\Program Files\OpenSSH.zip' -DestinationPath 'C:\Program Files\OpenSSH'
|
||||
rm 'C:\Program Files\OpenSSH.zip'
|
||||
powershell.exe -ExecutionPolicy Bypass -File 'C:\Program Files\OpenSSH\OpenSSH-Win64\install-sshd.ps1'
|
||||
```
|
||||
### Configure OpenSSH
|
||||
- start service
|
||||
```
|
||||
Start-Service sshd
|
||||
Set-Service -Name sshd -StartupType 'Automatic'
|
||||
Get-Service -Name sshd # check if running
|
||||
```
|
||||
- add firewall rule
|
||||
```
|
||||
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
|
||||
Get-NetFirewallRule | Where-Object DisplayName -Like '*ssh*'
|
||||
```
|
||||
- set PowerShell as default SSH shell
|
||||
```
|
||||
Set-ItemProperty "HKLM:\Software\Microsoft\Powershell\1\ShellIds" -Name ConsolePrompting -Value $true
|
||||
New-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
|
||||
```
|
||||
- add `charlotte.croce-adm` to the **Remote Management Users** groups
|
||||
- Add/uncomment the following lines in C:\ProgramData\ssh\sshd_config
|
||||
- `StrictModes no` is sometimes needed on Windows systems because Windows permissions don't map perfectly to the UNIX-style permissions that OpenSSH expects
|
||||
```
|
||||
AllowUsers charlotte\charlotte.croce-adm
|
||||
StrictModes no
|
||||
```
|
||||
## Ansible Setup
|
||||
### Inventory Setup
|
||||
- add windows machines to `inventory.txt`
|
||||
```
|
||||
[windows]
|
||||
mgmt01-charlotte
|
||||
wks01-charlotte
|
||||
[windows:vars]
|
||||
ansible_shell_type=powershell
|
||||
```
|
||||
- create ansible.cfg in ansible directory, to skip host key checking
|
||||
```
|
||||
[defaults]
|
||||
host_key_checking = false
|
||||
```
|
||||
- test connection
|
||||
```
|
||||
ansible windows -i inventory.txt -m win_ping -u charlotte.croce-adm@charlotte.local --ask-pass
|
||||
```
|
||||
|
||||
## Software deployment using win_chocolatey
|
||||
- create playbook `roles/windows_software.yml`
|
||||
```
|
||||
- name: install windows applications
|
||||
hosts: windows
|
||||
tasks:
|
||||
- name: install firefox and 7zip
|
||||
win_chocolatey:
|
||||
name:
|
||||
- firefox
|
||||
- 7zip
|
||||
state: present
|
||||
```
|
||||
- run playbook
|
||||
```
|
||||
ansible-playbook -i inventory.txt roles/windows_software.yml -u charlotte.croce-adm@charlotte.local --ask-pass
|
||||
```
|
||||
- If you encounter .NET Framework errors, install version 4.8 (in my case I needed version 4.8, it will probably be a different version in the future)
|
||||
```
|
||||
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2088631" -OutFile "C:\dotNetFx48.exe"
|
||||
Start-Process -FilePath "C:\dotNetFx48.exe" -ArgumentList "/quiet /norestart" -Wait
|
||||
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release # verify installation
|
||||
```
|
||||
> [!Note]
|
||||
> Installation may take several minutes. System restart required after installation.
|
||||
|
||||
- list packages installed with chocolatey
|
||||
```
|
||||
'C:\ProgramData\chocolatey\bin\choco.exe' list
|
||||
```
|
||||
|
69
sysadmin-ii-sys265/labs/lab06-ad-gpo-sw-deployment.md
Normal file
69
sysadmin-ii-sys265/labs/lab06-ad-gpo-sw-deployment.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
# AD Group Policy & SW Deployment
|
||||
|
||||
|
||||
## Prepare an OU, user & workstation
|
||||
Before we get into configuring a Group Policy Object (GPO) within Active Directory (AD), let’s set the AD stage to deploy a software package. Via AD Users & Computers, create a “Test OU”.
|
||||
|
||||

|
||||
|
||||
Use Powershell on AD01 via MGMT01 to create another OU called “Software Deploy”, move WKS01 and your regular named account into it, and then delete the Test OU.
|
||||
```powershell
|
||||
# Create another OU called Software Deploy under charlotte.local
|
||||
# Move WKS01 and your regular named account into it, and then
|
||||
# Delete the Test OU
|
||||
|
||||
# Get the domain Distinguished Name (DN)
|
||||
$domainDN = (Get-ADDomain).DistinguishedName
|
||||
|
||||
# Create the "Software Deploy" OU
|
||||
$swDeployOUDN = "OU=Software Deploy,$domainDN"
|
||||
$swDeployOU = Get-ADOrganizationalUnit -Identity $swDeployOUDN
|
||||
if($swDeployOU){
|
||||
Write-Host "'Software Deploy' OU already exists at $swDeployOUDN"
|
||||
}else{
|
||||
New-ADOrganizationalUnit -Name "Software Deploy" -Path $domainDN -Description "Software Deployment OU"
|
||||
Write-Host "Created $swDeployOUDN"
|
||||
}
|
||||
|
||||
# Move WKS01 computer to new OU
|
||||
$computerDN = (Get-ADComputer -Identity "WKS01-CHARLOTTE").DistinguishedName
|
||||
$targetOUDN = "OU=Software Deploy,$domainDN"
|
||||
Move-ADObject -Identity $computerDN -TargetPath $targetOUDN
|
||||
Write-Host "Computer $computerDN added to $targetOUDN"
|
||||
|
||||
# Move charlotte.croce-adm to new OU
|
||||
$userDN = (Get-ADUser -Identity "charlotte.croce-adm").DistinguishedName
|
||||
Move-ADObject -Identity $userDN -TargetPath $targetOUDN
|
||||
Write-Host "User $userDN added to $targetOUDN"
|
||||
|
||||
# Remove the "Protect from accidental deletion" flag from Test OU and delete
|
||||
$testOU = Get-ADOrganizationalUnit -Filter {Name -eq "Test OU"}
|
||||
if($testOU){
|
||||
Set-ADObject -Identity $testOU -ProtectedFromAccidentalDeletion $false
|
||||
Remove-ADOrganizationalUnit -Identity $testOU -Confirm:$false
|
||||
Write-Host "Deleted $testOU"
|
||||
}
|
||||
```
|
||||
|
||||
## Deploying Software via GPO
|
||||
|
||||
- On MGMT01, download the current Putty x64-bit Windows Installer Package.
|
||||
- Next, create a Share on MGMT01 named ‘Software’ and place Putty’s .msi in it, so users and computers (via GPO) can access & install it shortly.
|
||||
- see SYS255 file share docs [here](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md#use-rsat-to-add-to-fs01-and-create-a-sales-users-share). No need to map drive to letter
|
||||
- Via Group Policy Management feature on MGMT (You need to install this), create a new GPO named ‘Deploy SW’ within the Software Deploy OU. \
|
||||

|
||||

|
||||
- Edit the new GPO by creating a new Software installation, and assign Putty’s .msi package to deploy. \
|
||||

|
||||
- With the new GPO setting, run `gpupdate /force` on WKS01, and then allow the restart when prompted. PuTTY should now be installed
|
||||
|
||||
> [!Note]
|
||||
> An extremely common issue you’ll encounter in MS Window environments are the differences between Local Permissions vs. Share Permissions:
|
||||
>
|
||||
> Local Permissions (also called NTFS Permissions): Permissions that are applied only Locally (and not Remotely) on the OS, and affects both Local (i.e. via keyboard) and Remote (i.e. via network) account access.
|
||||
>
|
||||
> Share Permissions: Permissions that are applied only Remotely (and not Locally) to the OS, and affects only Remote (i.e. via network shares) account access.
|
||||
>
|
||||
> If both Shared & Local Permissions are set, then MOST RESTRICTIVE PERMISSION WINS. #LeastPriledgeRules -- summary [here](https://blog.netwrix.com/ntfs-vs-share-permissions)
|
||||
|
||||
|
149
sysadmin-ii-sys265/labs/lab07-certs.md
Normal file
149
sysadmin-ii-sys265/labs/lab07-certs.md
Normal file
|
@ -0,0 +1,149 @@
|
|||
# Lab07 - certs
|
||||
|
||||
make certain -adm account is in the Enterprise Admins
|
||||
```powershell
|
||||
Get-ADGroupMember "Enterprise Admins"
|
||||
```
|
||||
add RSAT to MGMT01. needs to run as administrator
|
||||
```powershell
|
||||
Install-WindowsFeature RSAT-ADCS -IncludeManagementTools
|
||||
```
|
||||
Start remote PowerShell session
|
||||
```powershell
|
||||
$session = New-PSSession -ComputerName ad01-charlotte
|
||||
```
|
||||
Install AD Certificate Services Role
|
||||
```powershell
|
||||
Invoke-Command -Session $session -ScriptBlock {
|
||||
Install-WindowsFeature -Name AD-Certificate -IncludeManagementTools
|
||||
|
||||
# Import the ADCS module
|
||||
Import-Module ADCSDeployment
|
||||
}
|
||||
```
|
||||
Configure Enterprise Root CA
|
||||
```powershell
|
||||
Invoke-Command -Session $session -ScriptBlock {
|
||||
Install-AdcsCertificationAuthority `
|
||||
-CAType EnterpriseRootCA `
|
||||
-CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
|
||||
-KeyLength 4096 `
|
||||
-HashAlgorithmName SHA512 `
|
||||
-ValidityPeriod Years `
|
||||
-ValidityPeriodUnits 7 `
|
||||
-Force
|
||||
}
|
||||
```
|
||||
Create Certificate Share
|
||||
```powershell
|
||||
Invoke-Command -Session $session -ScriptBlock {
|
||||
# create the shared folder for certs
|
||||
New-Item -Path "C:\Shares\Certs" -ItemType Directory -Force
|
||||
New-SmbShare -Name "Certs" -Path "C:\Shares\Certs" -FullAccess "Domain Admins" -ChangeAccess "Authenticated Users"
|
||||
|
||||
# copt cert to shared directory
|
||||
$cert = Get-ChildItem -Path "Cert:\LocalMachine\CA" | Where-Object {$_.Subject -like "*charlotte-ad01-CHARLOTTE-CA*"}
|
||||
|
||||
# export cert to shared folder
|
||||
Export-Certificate -Cert $cert -FilePath "C:\Shares\Certs\charlotte-AD01-CHARLOTTE-CA.cer" -Type CERT
|
||||
}
|
||||
```
|
||||
|
||||
Install AD CS role with Certification Authority and Web Enrollment
|
||||
```
|
||||
Install-WindowsFeature -Name ADCS-Cert-Authority, ADCS-Web-Enrollment -IncludeManagementTools
|
||||
```
|
||||
|
||||
Configure the Subordinate CA and generate certificate request
|
||||
```powershell
|
||||
Install-AdcsCertificationAuthority `
|
||||
-CAType EnterpriseSubordinateCA `
|
||||
-CACommonName "mgmt01-CHARLOTTE-SubCA" `
|
||||
-CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
|
||||
-KeyLength 4096 `
|
||||
-HashAlgorithmName SHA512 `
|
||||
-OutputCertRequestFile "C:\SubCARequest.req"
|
||||
```
|
||||
|
||||
Install the Web Enrollment service
|
||||
```powershell
|
||||
Install-AdcsWebEnrollment
|
||||
```
|
||||
|
||||
Move the certificate request to the Root CA, get it signed, and retrieve it
|
||||
```powershell
|
||||
# Copy request to Root CA's shared folder
|
||||
Copy-Item -Path "C:\SubCARequest.req" -Destination "\\ad01-charlotte\Certs\"
|
||||
|
||||
# Sign the request on the Root CA
|
||||
Invoke-Command -Session $session -ScriptBlock {
|
||||
# Sign the subordinate CA certificate request
|
||||
certreq -submit -config "ad01-charlotte\charlotte-AD01-CHARLOTTE-CA" -attrib "CertificateTemplate:SubCA" "C:\Shares\Certs\SubCARequest.req" "C:\Shares\Certs\SubCACert.cer"
|
||||
}
|
||||
|
||||
# Copy the signed certificate back to the Subordinate CA
|
||||
Copy-Item -Path "\\ad01-charlotte\Certs\SubCACert.cer" -Destination "C:\"
|
||||
```
|
||||
```powershell
|
||||
# Start the CA service
|
||||
Start-Service -Name CertSvc
|
||||
|
||||
# Install the issued certificate
|
||||
certutil -installcert "C:\SubCACert.cer"
|
||||
|
||||
# Configure CA settings
|
||||
certutil -setreg CA\CRLPeriodUnits 1
|
||||
certutil -setreg CA\CRLPeriod "Weeks"
|
||||
certutil -setreg CA\CRLOverlapPeriodUnits 12
|
||||
certutil -setreg CA\CRLOverlapPeriod "Hours"
|
||||
|
||||
# Restart the service to apply changes
|
||||
Restart-Service -Name CertSvc
|
||||
```
|
||||
```
|
||||
# Verify the CA status
|
||||
certutil -ping
|
||||
```
|
||||
|
||||
Clean up the remote session
|
||||
```
|
||||
Remove-PSSession $session
|
||||
```
|
||||
|
||||
___
|
||||
*at this point I stopped using PS and just used the GUI*
|
||||
___
|
||||
|
||||
### Create Certificate Template
|
||||
- open the CA console: `certsrv.msc`
|
||||
- Expand root cert tree > RC Certificate Templates > Manage
|
||||
- Duplicate User template
|
||||
- General tab: Set name "Champ Lab User"
|
||||
- Subject Name: Select "Build from AD info", uncheck all email options
|
||||
- Extensions: Add "Smart Card Logon" to Application Policies
|
||||
- Security: set "Authenticated Users" to Read, Enroll, Autoenroll permissions
|
||||
|
||||
## Issue Certificate Template
|
||||
- in CA console
|
||||
- Right-click Certificate Templates > New > Certificate Template to Issue > Select "Champ Lab User"
|
||||
|
||||
## Configure Group Policy
|
||||
- `gpmc.msc`
|
||||
- Create GPO "Champ Lab Users" at domain level
|
||||
- Edit GPO > User Configuration > Policies > Windows Settings > Security Settings > Public Key Policies
|
||||
- Enable "Certificate Services Client - Auto-Enrollment"
|
||||
- Check both renewal options > OK
|
||||
|
||||
## Test Auto-Enrollment
|
||||
- on WKS01:
|
||||
- `gpupdate /force`
|
||||
- Verify: `gpresult /r`
|
||||
- `certmgr.msc` > Personal > Certificates > Verify "Champ Lab User" certificate is present
|
||||
|
||||
## Windows Admin Center Installation
|
||||
- Download Windows Admin Center 2019 Evaluation
|
||||
- https://info.microsoft.com/ww-landing-windows-admin-center.html
|
||||
- download the msi
|
||||
- you will have to put in information. i just used fake info
|
||||
- Express setup. Generate self-signed cert. Disable updates
|
||||
- Logon via -adm account, add ad01 + wks10, install AD + DNS extensions, and uninstall Azure + Cluster extensions
|
72
sysadmin-ii-sys265/linux/centos7/secure-ssh.sh
Executable file
72
sysadmin-ii-sys265/linux/centos7/secure-ssh.sh
Executable file
|
@ -0,0 +1,72 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# secure-ssh.sh
|
||||
# author: charlottecroce
|
||||
#
|
||||
# creates a new SSH user using $1 parameter
|
||||
# adds a public key from the local repo or curled from the remote repo
|
||||
# removes roots ability to SSH in
|
||||
#
|
||||
#
|
||||
# Requirements:
|
||||
# must run as root
|
||||
# $1 = username of new user
|
||||
#
|
||||
|
||||
# check if script is run as root
|
||||
if [ $EUID -ne 0 ]; then
|
||||
echo "run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if username was provided
|
||||
if [ -z $1 ]; then
|
||||
echo "Usage: $0 <username>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# vars
|
||||
USERNAME=$1
|
||||
AUTHORIZED_KEYS_DIR="/home/$USERNAME/.ssh"
|
||||
AUTHORIZED_KEYS_FILE="$AUTHORIZED_KEYS_DIR/authorized_keys"
|
||||
|
||||
# create user
|
||||
useradd -m -d /home/$USERNAME -s /bin/bash $USERNAME
|
||||
echo "user: <$USERNAME> created"
|
||||
|
||||
# create .ssh directory, give perms to user
|
||||
mkdir -p $AUTHORIZED_KEYS_DIR
|
||||
chmod 700 $AUTHORIZED_KEYS_DIR
|
||||
|
||||
# try to get SSH pubkey from local repo
|
||||
if [ -f "/home/charlotte/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub" ]; then
|
||||
echo "key found in local repo"
|
||||
cat /home/charlotte/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub >> $AUTHORIZED_KEYS_FILE
|
||||
else
|
||||
# if local key doesn't exist, get from github repo...
|
||||
echo "no key found in local repo, cloning from github..."
|
||||
git clone https://git.charlotte.sh/lotte/ChamplainTechJournals /home/$USERNAME
|
||||
echo "retreived key from github repo"
|
||||
cat /home/$USERNAME/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub >> $AUTHORIZED_KEYS_FILE
|
||||
fi
|
||||
|
||||
echo "added key to $AUTHORIZED_KEYS_FILE"
|
||||
|
||||
# set perms, set new user as directory owner
|
||||
chmod 600 $AUTHORIZED_KEYS_FILE
|
||||
chown -R $USERNAME:$USERNAME $AUTHORIZED_KEYS_DIR
|
||||
|
||||
# disable root SSH login
|
||||
sed -i 's/PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
echo "Root SSH access has been disabled"
|
||||
|
||||
# disable password authentication
|
||||
sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
echo "Password authentication has been disabled"
|
||||
|
||||
# Restart SSH service
|
||||
echo "restarting ssh..."
|
||||
systemctl restart sshd
|
||||
|
||||
echo "complete!"
|
||||
|
1
sysadmin-ii-sys265/linux/public-keys/id_rsa.pub
Normal file
1
sysadmin-ii-sys265/linux/public-keys/id_rsa.pub
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCWgOr/kpF795P2RGym4lGHD+vXFPiTpkHIA7EjIX+/cF+XB1lZgRjjgcOMf19XjspJX4XAbrAFhX82XmIdpN0ljjspy7pPvvHjRa436LW2WYX0LB80ozZiRqTV0Ic9HOpEHKeVZCbBqoO44mMKLAlsaymuhZk1qvByxap3mjXeynd5N+tDXGltN18Nsflu3twMjfHepjbUgG4H+VzQbnItN2rIe8HWRt6MCisLCrplRWHCuOMRNMhtqhgkP5IX+XSPD4SMY2ZTCXCgRAZ1I2bwPV0YzjmXkaZur39bXh9UAr2ORhrAWR+IzgLpvjAr4hsXtYantnFu6Dp7ui/Ggs29OWYXoYaIWfD7UKdyz3/xPcg5MyYnL1KSLza5Odhj12lodrrskqwfunBIIRWjp0z6LuYxdZKj4mE7+wVWN6QQiSBkPZwfMbUf3OMSGB5krxVoOy/A6Ibg2FkgzONAHeUlW9L2inrry0jVxhuamDhGaOAjt1Rhq8asKZVRU1Er1DGtJaInN/z7gvBPIUsJbZRvJUj7EoB0RdGDcH/1U6UeSt5DXz9WRPaiEss/fv4N8snIj4hd9Jt774LR2UD8ZBQkOrFOH72noLx6GDrBeIZ//Hl8rO8ja+JyeVoNLqjKzwrLhbmPsdn2/zXB0asDq2vI0yk+YUlAldG38/lhZ/9EwQ== sys265
|
38
sysadmin-ii-sys265/network_configuration.md
Normal file
38
sysadmin-ii-sys265/network_configuration.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
# SYS265 - Network Configuration
|
||||
|
||||
## pfsense router/gateway/firewall
|
||||
upstream gateway: 10.0.17.2 \
|
||||
my unique WAN IP: 10.0.17.104 \
|
||||
net adapter 1: WAN \
|
||||
net adapter 2: LAN
|
||||
|
||||
### wks01-charlotte - Windows workstation
|
||||
IP address: 10.0.5.100/24 \
|
||||
Default Gateway: 10.0.5.2\
|
||||
DNS: 10.0.5.5
|
||||
|
||||
### ad01-charlotte - Windows server core
|
||||
IP Address: 10.0.5.5/24 \
|
||||
Gateway: 10.0.5.2\
|
||||
DNS: 10.0.5.2
|
||||
|
||||
### mgmt01-charlotte - Windows server
|
||||
IP address: 10.0.5.10/24 \
|
||||
Gateway: 10.0.5.2\
|
||||
DNS: 10.0.5.5
|
||||
|
||||
|
||||
### nmon1-charlotte -
|
||||
IP address: 10.0.5.11/24 \
|
||||
Gateway: 10.0.5.2 \
|
||||
DNS: 10.0.5.5
|
||||
|
||||
### web01-charlotte - web server
|
||||
IP address: 10.0.5.20/24
|
||||
Gateway: 10.0.5.2 \
|
||||
DNS: 10.0.5.5 \
|
||||
|
||||
### docker01-charlotte -
|
||||
IP address: 10.0.5.12/24
|
||||
Gateway: 10.0.5.2 \
|
||||
DNS: 10.0.5.5 \
|
97
sysadmin-ii-sys265/windows/dhcp_check.ps1
Normal file
97
sysadmin-ii-sys265/windows/dhcp_check.ps1
Normal file
|
@ -0,0 +1,97 @@
|
|||
# SYS265 - DHCP Lab
|
||||
# 1/31/25
|
||||
|
||||
# Get Username
|
||||
function get_username(){
|
||||
Write-Host 'Username:'$env:USERNAME
|
||||
}
|
||||
|
||||
# Get IP Address
|
||||
function get_ip(){
|
||||
$ip_address = (Get-NetIPAddress -AddressFamily IPv4 | Select IPv4Address | Where-Object { $_.IPv4Address -ne "127.0.0.1" } | Format-Table -HideTableHeaders | Out-String).Trim()
|
||||
Write-Host 'IP Address:'$ip_address
|
||||
}
|
||||
|
||||
# Get DHCP Server Address
|
||||
function get_dhcp(){
|
||||
$dhcp_address = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DHCPServer | Format-Table -HideTableHeaders | Out-String).Trim()
|
||||
Write-Host 'DHCP Server:'$dhcp_address
|
||||
$dhcp_lease = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DHCPLeaseExpires | Format-Table -HideTableHeaders | Out-String).Trim()
|
||||
Write-Host 'Lease Expiration:'$dhcp_lease
|
||||
}
|
||||
|
||||
# Get Gateway IP
|
||||
function get_gateway(){
|
||||
$gateway_address = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DefaultIPGateway | Format-Table -HideTableHeaders | Out-String).Trim()
|
||||
Write-Host 'Default Gateway:'$gateway_address
|
||||
}
|
||||
|
||||
# Get DNS Server IP
|
||||
function get_dns(){
|
||||
$dns_address = ((Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -ne "loopback" }).ServerAddresses | Out-String).Trim()
|
||||
Write-Host 'DNS Server:'$dns_address
|
||||
}
|
||||
|
||||
|
||||
clear
|
||||
|
||||
$Prompt = "`nChoose number for operation`n"
|
||||
$Prompt += "1. All`n"
|
||||
$Prompt += "2. Username`n"
|
||||
$Prompt += "3. IP`n"
|
||||
$Prompt += "4. DHCP`n"
|
||||
$Prompt += "5. Default Gateway`n"
|
||||
$Prompt += "6. DNS`n"
|
||||
$Prompt += "7. exit"
|
||||
|
||||
$operation = $true
|
||||
|
||||
while($operation){
|
||||
Write-Host $Prompt | Out-String
|
||||
$choice = Read-Host
|
||||
Write-Host "----------"
|
||||
|
||||
if($choice -eq 1){
|
||||
get_username
|
||||
get_ip
|
||||
get_dhcp
|
||||
get_gateway
|
||||
get_dns
|
||||
}
|
||||
|
||||
elseif($choice -eq 2){
|
||||
get_username
|
||||
}
|
||||
|
||||
|
||||
elseif($choice -eq 3){
|
||||
get_ip
|
||||
}
|
||||
|
||||
|
||||
elseif($choice -eq 4){
|
||||
get_dhcp
|
||||
}
|
||||
|
||||
elseif($choice -eq 5){
|
||||
get_gateway
|
||||
}
|
||||
|
||||
elseif($choice -eq 6){
|
||||
get_dns
|
||||
}
|
||||
|
||||
elseif($choice -eq 7){
|
||||
Write-Host "Goodbye" | Out-String
|
||||
exit
|
||||
$operation = $false
|
||||
}
|
||||
|
||||
else{
|
||||
Write-Host "Invalid Input" | Out-String
|
||||
}
|
||||
|
||||
Write-Host "----------"
|
||||
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue