https://github.com/epomatti/aws-ubuntu-landscape
Ubuntu Landscape environment
https://github.com/epomatti/aws-ubuntu-landscape
aws cis cis-benchmark ec2 landscape newrelic rdp terraform ubuntu ubuntu-landscape ubuntu-one ubuntu-pro xrdp
Last synced: about 2 months ago
JSON representation
Ubuntu Landscape environment
- Host: GitHub
- URL: https://github.com/epomatti/aws-ubuntu-landscape
- Owner: epomatti
- License: mit
- Created: 2024-09-30T19:53:45.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-25T20:25:07.000Z (8 months ago)
- Last Synced: 2025-02-25T21:19:37.245Z (8 months ago)
- Topics: aws, cis, cis-benchmark, ec2, landscape, newrelic, rdp, terraform, ubuntu, ubuntu-landscape, ubuntu-one, ubuntu-pro, xrdp
- Language: HCL
- Homepage:
- Size: 18.5 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Ubuntu Landscape
## Create the AWS resources
Securely connect to your profile with SSO:
```sh
export AWS_PROFILE=""
aws sso login
```Create the `.auto.tfvars` variables file:
```sh
cp config/template.tfvars .auto.tfvars
```Choose a current AMI from the [Canonical SSM index](https://documentation.ubuntu.com/aws/en/latest/aws-how-to/instances/find-ubuntu-images/). Example:
```sh
aws ssm get-parameters --names \
/aws/service/canonical/ubuntu/pro-server/24.04/stable/current/arm64/hvm/ebs-gp3/ami-id
```Set the required variables:
- `landscape_server_fqdn` - Internet FQDN for the Landscape server.
- `landscape_certbot_email` - Required while setting `certbot` certificates.Create the infrastructure:
```sh
terraform init
terraform apply -auto-approve
```## Setup the Ubuntu Landscape server
This project currently uses the `quickstart` mode for installation. The following are references for such configuration:
- [Ubuntu Pro Dashboard][1]
- [Landscape quickstart deployment][2]
- [Landscape self-hosted documentation][3]
- [Landscape self-hosted setup][4]Elevate your privileges in the server session:
```sh
sudo su -
```Make sure cloud init executed properly
```sh
cloud-init status
```> [!IMPORTANT]
> Make sure you don't skip the next step. Change the "example.com" to your owned domain of choice.Setup your domain registry for the `landscape.example.com` to the public IP or AWS EC2 instance name.
> [!NOTE]
> The project is created with an Elastic IP, therefore the public IP address will not change.Make sure that the DNS has replicated successfully before continuing:
```sh
dig landscape.example.com
```Attach the server to your Ubuntu Pro subscription. You're currently allowed 5 machines in the Personal free subscription.
> [!TIP]
> Don't need to attach again when using cloud Ubuntu Pro image```sh
pro attach
```Set the session variables:
```sh
export FQDN=$(aws ssm get-parameter --name "landscape-server-fqdn" --query "Parameter.Value" --output text)
export CERTBOT_EMAIL=$(aws ssm get-parameter --name "landscape-server-certbot-email" --query "Parameter.Value" --output text)
```Set your hostname using variables:
```sh
hostnamectl set-hostname "$FQDN"
```It would be a good idea to reboot after changing the hostname:
```sh
reboot
```Install Landscape:
```sh
apt update && DEBIAN_FRONTEND=noninteractive apt-get install -y landscape-server-quickstart
```Install your certificate:
> [!IMPORTANT]
> Make sure that after these steps the certificate is correctly issued and installed. This will required by the landscape client configuration later> [!TIP]
> If you rebooted, make sure to re-enter the required variables```sh
certbot --non-interactive --apache --no-redirect --agree-tos --email $CERTBOT_EMAIL --domains $FQDN
```Your server should be ready for use at `https://landscape.example.com`.
Access the server and create your administrator account.
In case this come in handy, these are the commands to manage the Landscape Server CTL:
```sh
lsctl status
lsctl restart
```## Ubuntu Pro Server
> [!NOTE]
> As of this writing, USG is not yet available for [24.04](https://ubuntu.com/security/certifications/docs/usg/cis).If you want to enable Ubuntu Pro for the created instance, just flip the variable switch:
```terraform
create_ubuntu_pro_server = true
```Check the pro licensing status:
> [!NOTE]
> USG and the Landscape client should already be installed. USG should already be enabled.> [!WARNING]
> Livepatch is currently [not supported](https://ubuntu.com/security/livepatch/docs/livepatch/explanation/which-are-the-supported-architectures) for ARM64 systems```sh
sudo pro status --all
```Link the instance to Landscape SaaS and then approve the registration:
```sh
# sudo is required to read /etc/landscape/client.conf
sudo landscape-config --computer-title "aws-ubuntu-pro-server" \
--account-name "" \
--http-proxy="" \
--https-proxy="" \
--script-users="root,landscape,nobody" \
--tags="server,aws"
```Enable script execution:
```sh
sudo landscape-config --include-manager-plugins=ScriptExecution --script-users=root,landscape,nobody
```Restart the service:
```sh
sudo service landscape-client restart
```Apply a profile:
```sh
sudo usg fix cis_level1_server
```## Ubuntu Desktop
This project uses a locally deployed bear metal remote Ubuntu 22.04 Desktop. Create a [Ubuntu image][5]. The recommended burning tool is [Balena][6].
> [!NOTE]
> Using Ubuntu 22.04 as of the time of this project Ubuntu Pro des not support 24.04 USG, which is part of this scope of experimentation.Make sure all packages are updated:
```sh
sudo apt update
sudo apt upgrade -y
```Set up XRDP to manage your machine remotely. This project follows this Digital Ocean's article.
```sh
sudo apt install xfce4 xfce4-goodies -y
sudo apt install xrdp -y
sudo systemctl status xrdp
```Once logged into your Ubuntu Desktop workstation, attach the machine for Ubuntu landscape management.
The `ubuntu-pro-client` should already be installed. Just make sure it is updated:
```sh
# This will update the client ot the latest version
sudo apt install -y ubuntu-pro-client
```> [!NOTE]
> You should be using a Let's Encrypt certificated issued earlier in this documentation. In for some reason you're opting for a self-signed approach, check how to [set it up in the client][8].Attach the Ubuntu Desktop machine to a license:
```sh
sudo pro attach
```Now, from your Ubuntu Landscape Server, follow the instructions on how to register a computer vi the menu. The path should be something like this:
```
https://landscape.example.com/account/standalone/how-to-register
```These are examples of commands to be executed in the Ubuntu Desktop client machine:
```sh
sudo apt-get update
sudo apt-get install -y landscape-client
# Replace the domain
sudo landscape-config --computer-title "MyUbuntuDesktop" --account-name standalone --url https://landscape.example.com/message-system --ping-url http://landscape.example.com/ping
```> [!NOTE]
> Make sure to check Ubuntu Pro status in Landscape to confirm it has been properly registered.### Enable script execution (administrator)
In case script execution needs to be enabled.
```sh
sudo -u landscape bash -x /opt/canonical/landscape/scripts/update_security_db.sh
```Configuration file:
```sh
/etc/landscape/client.conf
```Restarting the client:
```sh
sudo service landscape-client restart
```## Ubuntu Hardening
Ubuntu Pro supports [Ubuntu Security Guide (USG)][9]. For quick guide, the [tutorial][14] can be o good starting point.
Following the [installation guide][10]:
> [!NOTE]
> This is already covered by the previous steps already executed1. Install the UA client
2. Attach the subscriptionEnable and install USG:
```sh
sudo ua enable usg
sudo apt install usg
```This project uses CIS benchmarks, for which there are different [profiles][11]:
> [!TIP]
> Check the [CIS Benchmark publications][12] for in-depth details about each profile- Level 1: Balanced
- Level 2: RestrictiveTo apply the benchmark, select one of the profiles:
```sh
# Profiles: cis_level1_workstation, cis_level2_workstation
sudo usg fix
```A system `reboot` is required after this point.
Then, run the audit command:
> [!TIP]
> Once the audit below is completed, access the HTML page for analysis```sh
# Profiles: cis_level1_workstation, cis_level2_workstation
sudo usg audit
```To access the file from another user:
```sh
cp usg-report-xxx.html /home/user/Desktop/
chown : /home//Desktop/usg-report-20241110.1302.html
```To apply for a set of systems:
```sh
sudo usg generate-fix --output fix.sh
```If required, explore the [customization][13] options.
Other references include the [Ubuntu engagement][15] page, and the [CIS Benchmark Ubuntu][16] page.
## VirtualBox
Simplest way might be to use VirtualBox with Vagrant:
> [!NOTE]
> USG currently not supported for 24.04```sh
mkdir -p vagrant/ubuntu-jammy
cd vagrant/ubuntu-jammyvagrant init ubuntu/jammy64
vagrant up
vagrant ssh
```To increase the VM performance, set custom values:
```ruby
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus = "2"
end
```Setup Ubuntu Pro:
```sh
sudo apt update && sudo apt upgrade -y
sudo apt install -y ubuntu-advantage-tools
```Attach to a subscription:
```sh
sudo pro attach
```Enable and install USG, the Landscape Client:
```sh
sudo pro enable usg
sudo apt install -y usg landscape-client
```Set up the configuration file `/etc/landscape/client.conf`:
> [!TIP]
> The [documentation](https://ubuntu.com/landscape/docs/configure-landscape-client) have guidelines for CM tools such as Puppet or Ansible.```
[client]
log_level = info
url = https://{FQDN}/message-system
ping_url = http://{FQDN}/ping
data_path = /var/lib/landscape/client
registration_key = {REGISTRATION_KEY}
computer_title = {COMPUTER_TITLE}
account_name = {ACCOUNT_NAME}
include_manager_plugins = ScriptExecution
script_users = root,landscape,nobody
```With the file set, register the machine:
```sh
sudo landscape-config
```> [!WARNING]
> If you run into a "twisted.internet" error it might be due to [this bug](https://bugs.launchpad.net/landscape-client/+bug/1868730). Check the ownership of the `/var/lib/landscape/client` structure, it should have `landscape` ownership. If necessary, fix it by running `sudo chown -R landscape:landscape /var/lib/landscape/client`.Apply a USG a profile:
```sh
sudo usg fix cis_level1_server
```## Tuning
The client can read several variables to adjust the behavior.
An example is provided in the [repository](https://github.com/canonical/landscape-client/blob/main/example.conf), and this is a sample [question](https://answers.launchpad.net/landscape-client/+question/403745).
Configuration can be changed in the `client.conf` file:
```
/etc/landscape/client.conf
```For local debugging this might might be useful:
```conf
# The number of seconds between server exchanges
exchange_interval = 900 # 15 minutes# The number of seconds between urgent exchanges with the server.
urgent_exchange_interval = 60 # 1 minute# The number of seconds between pings.
ping_interval = 30# The number of seconds between apt update calls.
apt_update_interval = 21600# The number of seconds between package monitor runs.
package_monitor_interval = 1800# The number of seconds between snap monitor runs.
snap_monitor_interval = 1800
```Changing this configuration will require a client restart:
```sh
sudo service landscape-client restart
```## Troubleshooting
Make sure to run scripts with the right user `landscape`, or if `root` is used, apply the correct permissions.
```sh
sudo cat /etc/sudoers
groups landscape
```An example with the docker list:
```sh
stat /etc/apt/sources.list.d/docker.list
chmod -v o+r /etc/apt/sources.list.d/docker.list
```## Monitoring
### New Relic
Here's a New Relic example setup with log [forwarding](https://docs.newrelic.com/docs/logs/forward-logs/forward-your-logs-using-infrastructure-agent/#manual):
Configuration is declared in the `logging.yml` file:
```
/etc/newrelic-infra/logging.d/logging.yml
```Forward all the Landscape client logs:
```yaml
logs:
- name: landscape-client-logs
file: /var/log/landscape/*.log
attributes:
logtype: landscape-client
environment: sandbox
```Quick commands to manage the agents:
```sh
sudo systemctl newrelic-infra
sudo service landscape-client restart
```### Grafana
[Register a Linux server](https://epomatti.grafana.net/connections/add-new-connection/linux-node) with [Alloy](https://grafana.com/docs/alloy/latest/get-started/configuration-syntax/) to Grafana.
Configuration is derived from the following template files:
- https://storage.googleapis.com/cloud-onboarding/alloy/scripts/install-linux.sh
- https://storage.googleapis.com/cloud-onboarding/alloy/config/config.alloyYou can [configure Alloy](https://grafana.com/docs/alloy/latest/configure/) after it's installation:
```sh
/etc/alloy/config.alloy
```Checkout the Linux [detailed configuration](https://grafana.com/docs/alloy/latest/configure/linux/) page for instructions.
Commands to manage Alloy:
```sh
sudo systemctl reload alloy
sudo systemctl restart alloy
```For troubleshooting, enable the UI by passing [additional command-line flags](https://grafana.com/docs/alloy/latest/configure/linux/#pass-additional-command-line-flags).
Reference:
- [Introducing Grafana Alloy, A Distribution of the OTel Collector | GrafanaCON 2024 | Grafana](https://youtu.be/d9zLeFuIFIk)
- [Collect logs with Grafana Alloy](https://grafana.com/docs/grafana-cloud/send-data/logs/collect-logs-with-alloy/)## Mirrors / Repositories
This section will cover mirror configuration. Check out the [repository mirroring](https://ubuntu.com/landscape/docs/explanation-about-repository-mirroring) and [mirror management](https://ubuntu.com/landscape/docs/manage-repositories-web-portal) articles.
### EBS Modifications
> [!CAUTION]
> Watch out for EBS modifications rate limitBe mindful that there might be a 6 hour rate-limit for EBS.
If you reach the limit, then try this [resolution](https://repost.aws/knowledge-center/ebs-resolve-modify-volume-issues) procedure that involves attaching the instance to a new volume from a snapshot.
### CloudWatch
The CloudWatch Agent has been configured and installed by Terraform. Check its status, and [troubleshoot it](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/troubleshooting-CloudWatch-Agent.html) if necessary:
```sh
sudo systemctl status amazon-cloudwatch-agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
```### Mirror GPG Key Generation
> [!NOTE]
> You have to give a real name and email so that he key is generated, otherwise it won't. Check [this video](https://youtu.be/yduAcCqi2z0?list=PLnrmLjoInKWgQdNpMxuMC7rrdoDUgz6YZ) for reference.> [!IMPORTANT]
> Landscape mirror keys must not have passwords```sh
# Install and run rngd to improve the efficiency of generating the GPG key
sudo apt-get install rng-tools && sudo rngd -r /dev/urandom# Either 2 years, or never expire
gpg --gen-key
gpg --full-gen-key# List the public or secret keys
gpg -K
gpg --list-keys
gpg --list-secret-keys# Export it
gpg -a --export-secret-keys {SECRET_KEY_ID} > mirror-key.asc
```Just in case deleting a key is required:
```sh
gpg --delete-secret-key {SECRET_KEY_ID}
gpg --delete-key {SECRET_KEY_ID}
```### RabbitMQ Timeout
> [!TIP]
> Consider changing the [timeout](https://ubuntu.com/landscape/docs/configure-rabbitmq-for-landscape) for RabbitMQ```sh
sudo touch /etc/rabbitmq/rabbitmq
# Add this (5 hours): consumer_timeout = 18000000
sudo vim /etc/rabbitmq/rabbitmq
sudo rabbitmq-diagnostics environment | grep consumer_timeout
```### Create and Sync the Mirror
#### Volume Space
Packages are going to be downloaded to `/var/lib/landscape/landscape-repository/standalone/` by default.
Follow up the size with `du`:
```sh
du -h --max-depth=1 | sort -hr
```#### Pockets
It's important to understand this bit of the [documentation](https://ubuntu.com/landscape/docs/manage-repositories-with-the-API#heading--add-pockets-to-the-repository-profile):
> Landscape will take over the client's apt sources. The original `sources.list` file will be moved aside and only the ones enabled in Landscape will work.
Purpose for package management:
- `release` - Official release
- `security` - Critical security updates
- `updates` - Bug fixes and stability improvements. Tested and approved before being released.The pockets `proposed` and `backports` do not receive as much testing as `updates`.
This is a common recommendation:
```
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiverse
```#### Components
Components breakdown:
- `main` - Officially supported free software.
- `restricted` - Proprietary drivers and firmware supported by Ubuntu.
- `universe` - Community-maintained open-source packages.
- `multiverse` - Non-free software that Ubuntu does not officially support.#### PostgreSQL Mirror
On Landscape, add the distribution and the mirror. Example for PostgreSQL:
| Configuration | Value |
|---------------|------------------------------------------|
| Name | postgres |
| URI | https://apt.postgresql.org/pub/repos/apt |
| Series name | `jammy-pgs` |
| Pockets | `release` |
| Components | `main` |
| Architectures | `amd64` |Now sync the mirror.
Create a repository profile and save to the clients:
```sh
sudo ls -l /etc/apt/sources.list.d/
```### PPA
To configure PPA repositories we need to deconstruct the configuration process.
#### PPA Key
Go to https://launchpad.net/ and find the repository in the format `ppa:example/ppa`.
This example will use `ppa:graphics-drivers/ppa`.
If the key is not visible in there, manually create the following URL:
```
https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa
```Download the key manually. Use the `0x` prefix with followed by the last **16 digits** of the key, which are the key id:
```sh
curl -L "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xFCAE110B1118213C" -o graphics-drivers-ppa.asc
```Dearmor the key and copy it:
> [!NOTE]
> Either `/etc/apt/keyrings/` or `/etc/apt/trusted.gpg.d/` could be used based on security requirements.```sh
sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/graphics-drivers-ppa.gpg graphics-drivers-ppa.asc
sudo chmod 644 /etc/apt/trusted.gpg.d/graphics-drivers-ppa.gpg
```Confirm that the key is correctly installed:
```sh
sudo gpg --no-default-keyring --keyring /etc/apt/trusted.gpg.d/graphics-drivers-ppa.gpg --list-keys
```#### PPA APT Sources
In the cause of `graphics-drivers`, these are the examples for APT sources.
When storing the keys in `/etc/apt/trusted.gpg.d/`, the key should be trusted:
```
deb http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu jammy main
```If storing it under `/etc/apt/keyrings/`, then an explicit declaration is required:
```
deb [signed-by=/etc/apt/keyrings/graphics-drivers-ppa.asc] http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu jammy main
```#### Testing
Check if the package is available:
```sh
apt-cache search nvidia-driver-535
```Or installed if necessary:
```sh
apt install nvidia-driver-535
```### Issues with APT
```sh
sudo dpkg -r # or sudo dpkg -P
sudo apt purge
sudo apt clean
sudo apt --fix-broken install
sudo apt autoremove
```In some scenarios, a direct and / or forced removal might be necessary:
> [!NOTE]
> This can happen for example with this PostgreSQL [package conflict](https://github.com/saltstack-formulas/postgres-formula/issues/327).```sh
sudo dpkg -i --force-overwrite /var/cache/apt/archives/postgresql-client-common_272.pgdg22.04+1_all.deb
sudo apt --fix-broken install
```Other commands that can be used ([SO reference](https://askubuntu.com/questions/525088/how-to-delete-broken-packages-in-ubuntu)):
```sh
sudo dpkg --purge nodejs-legacy
```## Profiles
This [YouTube video](https://youtu.be/LreS6DhboYM) gives a run through the Profiles feature.
Demonstrate the usage of the [Profiles](https://ubuntu.com/landscape/docs/explanation-package-profile) feature:
- Repository
- Packages
- [Upgrade](https://ubuntu.com/landscape/docs/managing-computers#heading--manage-upgrade-profiles)
- Removal## API
Direct interaction with the API is possible via [API Endpoints](https://ubuntu.com/landscape/docs/make-rest-api-requests), such as with the [Packages API](https://ubuntu.com/landscape/docs/api-rest-packages).
## Postfix Email
Following the official [documentation](https://ubuntu.com/landscape/docs/configure-postfix-for-emails) but for Google's [SMTP Relay](https://support.google.com/a/answer/2956491?sjid=4703699716623319216-SA).
The SMTP Host will be the Gmail URL:
```
smtp.gmail.com
```To generate the credentials, one way is to use the [App Password](https://myaccount.google.com/apppasswords) feature. Reference from [linode](https://www.linode.com/docs/guides/configure-postfix-to-send-mail-using-gmail-and-google-workspace-on-debian-or-ubuntu/).
For deep dive details and troubleshooting, check the Ubuntu Server documentation [page](https://documentation.ubuntu.com/server/how-to/mail-services/install-postfix/).
Check for errors on both files:
```sh
sudo tail -f /var/log/mail.log
sudo tail -f /var/log/mail.err
```You may also want to check the `syslog`:
```sh
sudo tail -f /var/log/syslog
```## Miscellaneous
General configurations of various types: https://ubuntu.com/landscape/docs/other-classic-web-portal-tasks
[1]: https://ubuntu.com/pro/dashboard
[2]: https://ubuntu.com/landscape/docs/quickstart-deployment
[3]: https://ubuntu.com/landscape/docs/self-hosted-landscape
[4]: https://ubuntu.com/landscape/install
[5]: https://ubuntu.com/tutorials/create-a-usb-stick-on-windows
[6]: https://etcher.balena.io/
[7]: https://www.digitalocean.com/community/tutorials/how-to-enable-remote-desktop-protocol-using-xrdp-on-ubuntu-22-04
[8]: https://askubuntu.com/a/906249
[9]: https://ubuntu.com/security/certifications/docs/usg
[10]: https://ubuntu.com/security/certifications/docs/disa-stig/installation
[11]: https://ubuntu.com/security/certifications/docs/2204/usg/cis/compliance
[12]: https://downloads.cisecurity.org/#/
[13]: https://ubuntu.com/security/certifications/docs/2204/usg/cis/customization
[14]: https://ubuntu.com/tutorials/comply-with-cis-or-disa-stig-on-ubuntu#1-overview
[15]: https://ubuntu.com/engage/a-guide-to-infrastructure-hardening
[16]: https://www.cisecurity.org/benchmark/ubuntu_linux