Tuesday, June 11, 2024

Get remote openssl Certificate Information

$ openssl s_client -showcerts -servername example.com -connect example.com:443 </dev/null | openssl x509 -noout -dates -in -

...

notBefore=Feb 22 18:00:59 2024 GMT

notAfter=Feb 21 18:00:59 2026 GMT

Monday, June 10, 2024

Fix visual studio repeat key issue on mac vi

 red@mymac ~ % defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false


Monday, December 04, 2023

Running `go` From a Docker Container

 I followed instructions I found here: https://hub.docker.com/_/golang

% cat Dockerfile

FROM golang:1.21
WORKDIR /usr/src/app
# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN go build -v -o /usr/local/bin/app ./...
CMD ["app"]

You can use it like this ...

% cat hello.go
package main
import ("fmt")

func main() {
  fmt.Println("Hello World!")
}

% docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.21 go build /usr/src/myapp/hello.go

% docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.21 /usr/src/myapp/hello
Hello World!


Saturday, August 12, 2023

Ansible Unit Test Molecule Invert Failure into Success

 This is the use case where you are expecting a task to fail during the unit test.  There are cases where you would want to test for this.  Use your imagination. 


Anyways add this to the end of your molecule/*/converge.yml file:

---
- name: Converge
  hosts: all
  vars:

    ... omitted ...

    task_that_should_fail: 'Check if web server returns 200 on localhost'
  tasks:

    ... omitted ...

    - name: Role Should Fail In This Test
      block:
        - name: Include my_role
          ansible.builtin.include_role:
            name: "my_role"
          ignore_errors: true

        - name: Passed is Fail
          fail:
            msg: "Role my_role unexpectedly successed!"

      rescue:
        - name: Failed is Pass
          debug:
            msg: "Role my_role failed when it should have!"
          when:
            - ansible_failed_task.name == task_that_should_fail

        - name: Passed is Fail
          fail:
            msg: "Role my_role unexpectedly succeed!"
          when:
            - not ansible_failed_task.name == task_that_should_fail

Wednesday, August 02, 2023

How to Add the Current Time to the Results of Your MySQL Select Statements

 MariaDB [xx_config]> select *, NOW() from servers where id = 'Fakeuuid-kinda'; 
| ID              |  VERSION |  NOW()    
| Thing One | Thing Two  | 2023-08-03 02:57:44 

Tuesday, August 01, 2023

What Data Directory is MariaDB 10.6 using?

 Run this SQL query ...

root@xoubdmz1:~ # mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 587
Server version: 10.6.14-MariaDB-1:10.6.14+maria~ubu2204-log mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.001 sec)

MariaDB [(none)]>

Friday, June 16, 2023

vi mk%y'k

Copy lines of text between '{}'s 

Give this text file contents:

  1
  2 ; <<>> DiG 9.10.6 <<>> download.fedoraproject.org
  3 ;; global options: +cmd
  4 ;; Got answer:
  5 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52209
  6 ;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 1
  7
  8 ;; OPT PSEUDOSECTION:
  9 ; EDNS: version: 0, flags:; udp: 512
 10 ;; QUESTION SECTION:
 11 ;download.fedoraproject.org.    IN      A
 12 {
 13 ;; ANSWER SECTION:
 14 download.fedoraproject.org. 300 IN      CNAME   wildcard.fedoraproject.org.
 15 wildcard.fedoraproject.org. 22  IN      A       38.145.60.20
 16 wildcard.fedoraproject.org. 22  IN      A       152.19.134.142
 17 wildcard.fedoraproject.org. 22  IN      A       67.219.144.68
 18 wildcard.fedoraproject.org. 22  IN      A       8.43.85.67
 19 wildcard.fedoraproject.org. 22  IN      A       38.145.60.21
 20 wildcard.fedoraproject.org. 22  IN      A       152.19.134.198
 21 wildcard.fedoraproject.org. 22  IN      A       8.43.85.73
 22 wildcard.fedoraproject.org. 22  IN      A       140.211.169.196
 23 wildcard.fedoraproject.org. 22  IN      A       34.221.3.152
 24 }
 25 (
 26 ;; Query time: 95 msec
 27 ;; SERVER: 2600:6c52:763f:e773:1691:82ff:fe86:3046#53(2600:6c52:763f:e773:1691:82ff:fe86:3046)
 28 ;; WHEN: Fri Jun 16 21:31:33 PDT 2023
 29 ;; MSG SIZE  rcvd: 222
 30 )

Move the cursor to the '{' on line 12. (:12<return>) then type: mk%y'k then move the cursor to line 7 and type: p and the file should look like this:

  1
  2 ; <<>> DiG 9.10.6 <<>> download.fedoraproject.org
  3 ;; global options: +cmd
  4 ;; Got answer:
  5 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52209
  6 ;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 1
  7 {
  8 ;; ANSWER SECTION:
  9 download.fedoraproject.org. 300 IN      CNAME   wildcard.fedoraproject.org.
 10 wildcard.fedoraproject.org. 22  IN      A       38.145.60.20
 11 wildcard.fedoraproject.org. 22  IN      A       152.19.134.142
 12 wildcard.fedoraproject.org. 22  IN      A       67.219.144.68
 13 wildcard.fedoraproject.org. 22  IN      A       8.43.85.67
 14 wildcard.fedoraproject.org. 22  IN      A       38.145.60.21
 15 wildcard.fedoraproject.org. 22  IN      A       152.19.134.198
 16 wildcard.fedoraproject.org. 22  IN      A       8.43.85.73
 17 wildcard.fedoraproject.org. 22  IN      A       140.211.169.196
 18 wildcard.fedoraproject.org. 22  IN      A       34.221.3.152
 19 }
 20
 21 ;; OPT PSEUDOSECTION:
 22 ; EDNS: version: 0, flags:; udp: 512
 23 ;; QUESTION SECTION:
 24 ;download.fedoraproject.org.    IN      A
 25 {
 26 ;; ANSWER SECTION:
 27 download.fedoraproject.org. 300 IN      CNAME   wildcard.fedoraproject.org.
 28 wildcard.fedoraproject.org. 22  IN      A       38.145.60.20
 29 wildcard.fedoraproject.org. 22  IN      A       152.19.134.142
 30 wildcard.fedoraproject.org. 22  IN      A       67.219.144.68
 31 wildcard.fedoraproject.org. 22  IN      A       8.43.85.67
 32 wildcard.fedoraproject.org. 22  IN      A       38.145.60.21
 33 wildcard.fedoraproject.org. 22  IN      A       152.19.134.198
 34 wildcard.fedoraproject.org. 22  IN      A       8.43.85.73
 35 wildcard.fedoraproject.org. 22  IN      A       140.211.169.196
 36 wildcard.fedoraproject.org. 22  IN      A       34.221.3.152
 37 }
 38 (
 39 ;; Query time: 95 msec
 40 ;; SERVER: 2600:6c52:763f:e773:1691:82ff:fe86:3046#53(2600:6c52:763f:e773:1691:82ff:fe86:3046)
...


Wednesday, June 07, 2023

Remove last column in bash

awk -F'.' 'sub(FS $NF,x)' file

bash-3.2$ cat file
MOR22A2.S4000011.h23v22.061.2023063111017.hdf
MOR22A2.S4000011.h23v44.061.2023061111033.hdf
AST006_S003.zip
AST003_S066.zip
bash-3.2$ awk -F'.' 'sub(FS $NF,x)' file
MOR22A2.S4000011.h23v22.061.2023063111017
MOR22A2.S4000011.h23v44.061.2023061111033
AST006_S003
AST003_S066

Wednesday, May 03, 2023

Ansible code to update AWX Ansible Inventory

Ansible code to update AWX Ansible Inventory

Here is the playbook:

---
- name: Update Inventory
  hosts: localhost
  gather_facts: False   roles:
    - role: roles/update_inventor
y

localhost is used for hosts: because the AWX REST API endpoints are accessible from the Ansible master we are running on.


Use that playbook in an AWX Job Template

  • The job template needs to prompt the user for "Inventory" on launch.
Respond with the inventory the hosts you wish to update are in. This will provide the value to the special AWX variable tower_inventory_id. 
  • The job template needs to prompt the user for "Variables" on launch.
Example:
---
update_ati_fqdns:
- host1.example.com
- host2.example.com
ansible_connection: 'local'
  • You will need a survey for your Job Template
    • Admin Username: admin_username
    • Admin User Password: admin_password
    • URL for AWX REST API GROUP endpoint: http://awx.example.com/api/v2/groups
    • update_ati_group: integer
    • Action: pulldown [REMOVE_FROM_GROUP, ADD_TO_GROUP]

Here is the role:


defaults/main.yml --- awx_base_url: "https://awx.example.com"
tasks/main.yml --- - name:   ansible.builtin.include_tasks: test_block_loop.yml   loop: "{{ update_ati_fqdns }}"

tasks/test_block_loop.yml

--- - name: Get Host ID   uri:     url: "{{ awx_base_url }}/api/v2/inventories/{{ tower_inventory_id }}/hosts/?name={{ item }}"     method: GET     user: "{{ admin_username }}"     password: "{{ admin_password }}"     force_basic_auth: yes     validate_certs: no     headers:       Content-Type: "application/json"   register: host_result   failed_when: host_result.status != 200 or host_result.json.count != 1 - name: "Set payload for add."   set_fact:     body: "{ \"id\" : {{ host_result.json.results[0].id | int }} }" - name: "Set payload for disassociate/remove."   set_fact:     body: "{ \"disassociate\" : {{ host_result.json.results[0].id | int }}, \"id\" : {{ host_result.json.results[0].id | int }} }"   when: selected_action == "REMOVE_FROM_GROUP" - name: Update Ansible Tower inventory   uri:     url: "{{ update_ati_groups_api }}/{{ update_ati_group }}/hosts/"     user: "{{ admin_username }}"     password: "{{ admin_password }}"     method: "POST"     body: "{{ body }}"     force_basic_auth: yes     status_code: 204     body_format: json     validate_certs: no

Wednesday, March 22, 2023

Get process ids and command on Linux without `ps` command

bash-4.4$ for exe in /proc/*/exe; do ls -l $exe; done
lrwxrwxrwx 1 runner root 0 Mar 22 22:47 /proc/1/exe -> /usr/local/bin/dumb-init
lrwxrwxrwx 1 runner root 0 Mar 22 22:47 /proc/1039/exe -> /usr/bin/vi
lrwxrwxrwx 1 runner root 0 Mar 16 03:15 /proc/143/exe -> /usr/bin/bash
lrwxrwxrwx 1 runner root 0 Mar 17 22:44 /proc/1685/exe -> /usr/bin/bash
lrwxrwxrwx 1 runner root 0 Mar 16 03:04 /proc/17/exe -> /usr/bin/receptor
lrwxrwxrwx 1 runner root 0 Mar 18 03:21 /proc/1788/exe -> /usr/bin/bash
lrwxrwxrwx 1 runner root 0 Mar 22 22:45 /proc/2137/exe -> /usr/bin/bash
lrwxrwxrwx 1 runner root 0 Mar 22 22:47 /proc/self/exe -> /usr/bin/coreutils
lrwxrwxrwx 1 runner root 0 Mar 22 22:47 /proc/thread-self/exe -> /usr/bin/coreutils

Friday, December 23, 2022

Trouble Shooting LDAP Authentication with Ansible AWX

 If you are having trouble getting your AWX deployment to preform authentication with LDAP you might want to make sure that the container that runs the AWX web server can talk to the LDAP server over a encrypted connection.  To do this follow these steps:

1) List your AWX pods like so:

kubectl -n awx get pods

You are looking for the pod that has the 4 containers.  In my case this is pod, awx-demo-8ded6678-gk322.  

2) "exec" onto the awx-demo-web container like so:

kubectl -n awx exec -it awx-demo-8ded6678-gk322 -c awx-demo-web -- /bin/bash 


3) Check the secure connection to the LDAP server

From the bash prompt on the container execute:

echo | openssl s_client -connect ldap.example.com:636

Check the output.  Are you getting output? You can check the dates on the certificate like so:

echo | openssl s_client -connect ldap.example.com:636 2> /dev/null | openssl x509 -noout -dates

 

So You Disabled built-in authentication system on AWX and you are locked out.

So You Disabled built-in authentication system on AWX and you're locked out.  Do not panic I have done the same and here is how I fixed it.  Here is the screen I am talking about:



DO NOT CLICK THAT UNLESS YOU ARE SURE YOU CAN LOG BACK IN! As soon as you click that link you are logged out and will probably not be able to log in ... hence this blog post. :)


I had deployed AWX by installing awx-operator & awx-demo on to a K3s cluster.  Well, I clicked on the "Disable ..." link because I thought I needed to do that to get LDAP authentication to work.  I was wrong and I was locked out of the AWX UI!  

What happens when you click that link is that AWX updates a table, config_settings, so that the rest of the AWX systems know that the builtin authentication is disabled.  So what you need to do is update that row in the database.  And here is how you do that.

1) List your AWX pods like so:

kubectl -n awx get pods

You are looking for the pod that has the 4 containers.  In my case this is pod, awx-demo-8ded6678-gk322.  

2) "exec" onto the awx-demo-web container like so:

kubectl -n awx exec -it awx-demo-8ded6678-gk322 -c awx-demo-web -- /bin/bash 

This will give you a "bash-5.1$ " prompt.  Use this prompt to enter the commands below.

3) Dump the DB creds.

cat /etc/tower/conf.d/credentials.py

4) Logon to the database

psql -h awx-demo-postgres-13

I got awx-demo-postgres-13 from step 3 above. Enter the password that was in the credentials.py file.

5) Update the conf_setting table

From the psql prompt, awx=#,  execute this SQL:

update conf_setting set value = false where key = 'DISABLE_LOCAL_AUTH' 

I forget if I needed to restart anything.  But you could try deleting the pod if you still can't login. 

 

Thursday, December 22, 2022

Trouble shooting AWX LDAP Authentication Issue

 I have a K3s cluster and I set up my AWX server by installing awx-operator.  I also have an OpenLDAP server.  My OpenLDAP server has a signed valid TLS Cert and works fine.

Next I log on to my AWX server as the 'admin' user. 

You get the password for this account by executing:

kubectl get secret awx-demo-admin-password -o jsonpath={.data.password} | base64 --decode

I navigate to "Settings > LDAP Default" and filled out the form.  Set:

  • "LDAP Server URI" to my ldap server ldaps://ldap.example.com.
  • "LDAP Bind DN" to cn=Manager,dc=example,dc=com
  • "LDAP Bind Password" to the correct password you would use with `ldapsearch`.
  • "LDAP Group Type" to PosixGroupType
  • "LDAP User Search" to ["ou=users,dc=example,dc=com","SCOPE_SUBTREE","(uid=%(user)s)"]
  • "LDAP Group Search" to ["OU=Groups,dc=example,dc=com","SCOPE_SUBTREE","(objectClass=posixGroup)"]
Everything else leave as default.  Note: Of course I used my actual domain name and NOT example.com.

Then I tried to log into the AWX UI with my LDAP user account but couldn't log in.  I spent days reading documentation and try things.  I even accidentally locked my admin account out by clicking on "Disable the built-in authentication system" Off link. DO NOT DO THAT! I had to run an update to a table in the postgresql database to fix that.

Here is how I finally came to realize that I was entering the wrong password.
I would "tail" the log of the "awx-demo-web" container with this command:

kubectl -n awx get pods
...
kubectl -n logs -f awx-demo-9aidd-gk6dy awx-demo-web
...
and you will see messages like:

WARNING ... awx.api.generics Login failed for user red.cricket from 10.0.0.5
WARNING ... django.request Unauthorized: /api/login/
WARNING ... django.request Unauthorized: /api/login/

But nothing that will tell you why the login failed.  To see why you need to change the logging level on the AWX server to DEBUG. And to do that you navigate to "Settings > Logging" and click the Edit button, then change the "Logging Aggregator Level Threshold"to "DEBUG".

Then when you attempt to login with the wrong password you will see this output in the logs:

DEBUG ... django_auth_ldap search_s(...) returned 1 objects: uid=red.cricket...
DEBUG ... django_auth_ldap Authentication failed for red.cricket: user DN/password rejected by LDAP server.

Once you have figured out what is wrong and how to correct it be sure change the logging level back to INFO.

Saturday, February 19, 2022

Check if remote port is open

 ref. 

https://www.fosslinux.com/35730/5-ways-to-check-if-a-port-is-open-on-a-remote-linux-pc.htm

$ nc -zvw10 192.168.0.1 22
$ nmap 192.168.0.2 -p 103
$ telnet [IP or Hostname] [PortNumber]
echo > /dev/tcp/[host]/[port] && echo "Port is open"
echo > /dev/udp/[host]/[port] && echo "Port is open"
netstat -tuplen

netstat -tuplen will output the whole list of the IP addresses. The entries that have “Listen” in the “State” column are the open ports.


Wednesday, November 14, 2018

Debugging django queries with logger. ref. https://stackoverflow.com/questions/6574003/django-limiting-query-results

In [19]: import logging                                 
In [20]: l = logging.getLogger('django.db.backends')    
In [21]: l.setLevel(logging.DEBUG)                      
In [22]: l.addHandler(logging.StreamHandler())      
In [23]: User.objects.all().order_by('-id')[:10]          
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]

Friday, August 25, 2017

Monday, May 23, 2016

Doing video screen capture with AndroidStudio and lbgdx games

I had to use these settings ...
... to get my video game to operate correctly when doing screen capture.

Friday, April 15, 2016

Setting root password for a Centos Cloud image

[red@vm-red ~]$ guestfish --rw -a ./CentOS-6-x86_64-GenericCloud-1508.qcow2 

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help on commands
      'man' to read the manual
      'quit' to quit the shell

><fs> run
 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00
><fs> list-filesystems
/dev/sda1: ext4
><fs> mount /dev/sda1 /
><fs> vi /etc/shadow

><fs> 


Note above not tested on Centos7