Hello fellow F5 admins,
currently I try to established a workflow, where new vcmp guests are created and configured with a standard basic config (and even building a HA setup).
The creation part is working, but here begin the problems:
tl;dr
Question: What is the proper way to bootstrap a freshly installed vcmp guests (or appliance), when you are forced to change the default passwords on 1st login, without doing it by hand?
The only solution I found (link below) will lock me out of the system forever.
Long Version:
Freshly installed systems enforce a password change for admin user on 1st access. This password change cannot be accomplished with the standard ansible module “bigip_user”. If you try, you will get an error telling you, password has expired and it has to be changed.
I then found an article about the security password policy and how one is supposed to change the password with ansible (https://techdocs.f5.com/en-us/bigip-14-0-0/big-ip-system-secure-password-policy/secure-password-policy-chapter-title.html)
So I gave it a try and the password was changed “a” password, but not the one provided by the playbook variable. Neither GUI nor SSH or REST login will work. I am locked out.
Befor you ask: yes the password in ansible-vault style is correct, because it is used to create the guest on the vcmp hosts.
Here is my playbook:
---
- name: Test vCMP-Guest
hosts: vcmp_guests
gather_facts: false
vars:
f5_api_admin_user: admin
f5_api_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
35613438373864653838386266616364666366363332646635303036343266646664656333643932
6462363934306365636265313038376436353032303330370a656434643837343165316333393932
66616133376433303136366664303563373034353630656531663864323433663166653539303937
3937646663613064390a663631623733376339353735633362633139383635386661376137653434
6237
bigip_provider:
server: "{{ ansible_host }}"
server_port: 443
user: "{{ f5_api_admin_user }}"
password: "{{ f5_api_admin_password }}"
validate_certs: false
transport: rest
tasks:
- name: Set admin Password
uri:
url: "https://{{ ansible_host }}/mgmt/shared/authz/users/admin"
method: PATCH
body: '{"oldPassword":"admin","password":"{{ f5_api_admin_password }}"}'
body_format: json
validate_certs: false
force_basic_auth: true
user: admin
password: admin
headers:
Content-Type: "application/json"
register: result
delegate_to: localhost
- name: Debug
ansible.builtin.debug:
var: result
- name: Try to get system info
f5networks.f5_modules.bigip_device_info:
gather_subset:
- system-info
provider: "{{ bigip_provider }}"
register: output
delegate_to: localhost
- name: Debug
ansible.builtin.debug:
var: output
The Output of the the password reset task look fine to me:
TASK [Debug] ********************************************************************************************************************************************************************************
task path: ~/guest-playbook.yml:47
ok: [test-guest] => {
"result": {
"cache_control": "no-store, no-cache, must-revalidate",
"changed": false,
"connection": "close",
"content_length": "330",
"content_security_policy": "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data: http://127.4.1.1 http://127.4.2.1",
"content_type": "application/json; charset=UTF-8",
"cookies": {},
"cookies_string": "",
"date": "Fri, 29 Sep 2023 11:48:50 GMT",
"elapsed": 0,
"expires": "-1",
"failed": false,
"json": {
"displayName": "Admin User",
"encryptedPassword": "<removed>",
"generation": 0,
"kind": "shared:authz:users:usersworkerstate",
"lastUpdateMicros": 0,
"name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"selfLink": "https://localhost/mgmt/shared/authz/users/********",
"shell": "/sbin/nologin"
},
"msg": "OK (330 bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "Jetty(9.2.22.v20170606)",
"status": 200,
"strict_transport_security": "max-age=16070400; includeSubDomains",
"url": "https://<removed>/mgmt/shared/authz/users/********",
"x_content_type_options": "nosniff",
"x_frame_options": "SAMEORIGIN",
"x_xss_protection": "1; mode=block"
The next task, will already fail with a “unauthorized” message. From now on, I cannot access the system any more, and believe me, I tried a lot.
One interesting Thing:
When I don’t use a ansible-vault encrypted password and instead set the variable directly to the string, login is possible, BUT only to the GUI. I cannot do rest api calls with this password. When I change the admin password again (from within GUI), I can however use rest api again. When I change it back to the original one, api calls will fail.
There is one difference I noticed in /var/log/audit in the case, when I set the password as clear-text:
User authentication is logged like this and the api request fails:
AUDIT - user admin - RAW: httpd(pam_audit): User=admin tty=(unknown)
After setting a new password within the GUI oder tmsh and running the same api request, audit messaged changed like this and the request is successfull:
[...] AUDIT - user admin - RAW: rest(pam_audit): user=admin(admin)[...]
When I now change the password back to the previous one, api request fails again
[...]AUDIT - user admin - RAW: httpd(pam_audit): User=admin tty=(unknown)[...]
What on earth is going on?
How is one supposed to bootstrap a vcmp guest from ground up without manually interaction for setting passwords and stuff?
Any usefull advice is thoroughly appreciate.
Cheers
Ichnafi