Upgrade awx-cli:

pip install ansible-tower-cli --upgrade

awx-cli config verify_ssl False

Backup AWX

Make sure AWX containers are running and you can login to Web GUI

docker ps

Export Credentials, Inventories, Job templates and Workflows

awx-cli receive -u admin -p 'password' -h http://awx-old --credential all > credential.json
awx-cli receive -u admin -p 'password' -h http://awx-old --project all > project.json
awx-cli receive -u admin -p 'password' -h http://awx-old --inventory all > inventory.json
awx-cli receive -u admin -p 'password' -h http://awx-old --job_template all > job_template.json
awx-cli receive -u admin -p 'password' -h http://awx-old --workflow all > workflow.json

Installing new AWX (on new machine)

Install epel-relase, AWX prerequisites,Docker, docker-compose and Ansible

yum install -y epel-release 
yum -y install git gcc gcc-c++ nodejs gettext device-mapper-persistent-data lvm2 bzip2 python-pip
yum-config-manager --addrepo=https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
# Enable and start Docker service
systemctl enable --now docker.service
# install docker-compose
pip install docker-compose
# install Ansible
yum install ansible
# Start and enable Ansible
systemctl enable ansible && systemctl start ansible

Installing Ansible AWX 

git clone --depth 50 https://github.com/ansible/awx.git
#  set a custom admin_password for AWX and PostgreSQL in inventory file.
cd awx/installer
sed -i 's|admin_password=.*|admin_password=pass|g' inventory
# Add secret_key in inventory file.
openssl rand -base64 30
lE7TAtB/EGDfZp2vYJWY1jVwn3nDh3H+a0pqhXHZ
sed -i 's|secret_key=.*|secret_key=lE7TAtB/EGDfZp2vYJWY1jVwn3nDh3H+a0pqhXHZ|g' inventory

Customize other directives if needed in inventory file, for example host_port=9000 and postgres folder – postgres_data_dir = "/data"

Install AWX Ansible

ansible-playbook -i inventory install.yml

# Check if all 5 containers are installed
docker ps

Allow HTTP/HTTPS service in Linux firewall

firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

In this example, AWX will be available on port 9000

Try Logging in: http://awx-new:9000

Redirecting HTTP traffic to HTTPS

We’ll use nginx as reverse proxy to redirect HTTP traffic on port 9000 to HTTPS.

yum install nginx
systemctl enable nginx

Create self-signed certificate:

cd /etc/awx
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/awx/awx.key -out /etc/awx/awx.crt

Generating a 2048 bit RSA private key
.....................................+++
.........................................................+++
writing new private key to '/etc/awx/awx.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:SR
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:Zemoon
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:awx-new.test.com
Email Address []:

Edit /etc/nging/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  awx-new.test.com;
        add_header Strict-Transport-Security max-age=2592000;
        rewrite ^ https://$server_name$request_uri? permanent;
        root         /example;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }


server
{
 listen 443 ssl http2;
 server_name awx-new.test.com;

location /
 {
   proxy_http_version 1.1;
   proxy_set_header Host $host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";
   proxy_pass http://192.168.1.2:9000/;
 }

ssl on;
ssl_certificate /etc/awx/awx.crt;
ssl_certificate_key /etc/awx/awx.key;
ssl_session_timeout 5m;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5:HIGH:!aNULL;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

access_log /var/log/nginx/awx.access.log;
error_log /var/log/nginx/awx.error.log;
}

Start nginx (systemctl start nginx) and try accessing AWX https://awx-new.test.com

Restoring AWX

Install awx-cli

pip install ansible-tower-cli --upgrade

awx-cli config verify_ssl False

Manually create organization: Organizations-“plus” sign

Create Teams (if you had any on old AWX)

# Restore Credentials 

awx-cli send -u admin -p 'pass' -h http://awx-new.test.com:9000 credential.json

#P lease note that passwords won't be exported, you'll need to enter it # manually after usernames are imported (Credentials section in Web GUI)

 # restore project

awx-cli send -u admin -p 'pass' -h http://awx-new.test.com:9000 project.json

# restore inventories

awx-cli send -u admin -p 'pass' -h http://awx-new.test.com:9000 inventory.json

# before restoring job templates, remove line which contains string credential

sed -i '/\bcredential\b/d' job_template.json

# restore job templates

awx-cli send -u admin -p 'pass' -h http://awx-new.test.com:9000 job_template.json

# restore workflows

awx-cli send -u admin -p 'pass' -h http://awx-new.test.com:9000 workflow.json

Active Directory Authentication

LDAP config won’t be exported so we need to set it up manually: In Web portal click Settings-Authentication-LDAP

LDAP SERVER: default

LDAP SERVER URI: ldap://1.2.3.4:389

LDAP BIND DN: CN=Ansible,OU=ServiceUsers,OU=test,DC=com

LDAP BIND PASSWORD: password

LDAP GROUP TYPE: ActiveDirectoryGroupType

LDAP USER SEARCH: [
 "OU=Users,OU=test,DC=com",
 "SCOPE_SUBTREE",
 "(sAMAccountName=%(user)s)"
]
 
LDAP GROUP SEARCH: [
 "CN=Users,DC=test,DC=com",
 "SCOPE_SUBTREE",
 "(objectClass=group)"
]

LDAP ORGANIZATION MAP: {
 "My Organization": {
  "remove_admins": false,
  "admins": "CN=Ansible, OU=Security,OU=Groups,OU=test,DC=com"
 }
}

 

In this example SCCM and SQL services are monitored by NCPA agent.

Open host configuration file /usr/local/nagios/etc/objects/conf.d/hostname.cfg

Add following lines:

define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SMS Agent host
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=CcmExec,status=running'
        }


define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SMS EXECUTIVE
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SMS_EXECUTIVE,status=running'
        }

define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SMS NOTIFICATION SERVER
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SMS_NOTIFICATION_SERVER,status=running'
        }


define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SMS SITE COMPONENT MANAGER
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SMS_SITE_COMPONENT_MANAGER,status=running'
        }


define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SMS SITE SQL BACKUP
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SMS_SITE_SQL_BACKUP,status=running'
        }

define service{
        use                             generic-service
        host_name                       sccm.test.com 
        service_description             SMS SITE VSS WRITER
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SMS_SITE_VSS_WRITER,status=running'
        }


define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SQL Server
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=MSSQLSERVER,status=running'
        }


define service{
        use                             generic-service
        host_name                       sccm.test.com
        service_description             SQL Server Reporting Services
        check_command                   check_ncpa!-t 'API KEY' -P 5693 -M 'services' -q 'service=SQLServerReportingServices,status=running'
        }

Service name can be found in services.msc snap-in

Restart nagios systemctl restart nagios and new services should appear for host.

Script for concatenating first_name, last_name and address into ResourceName column, and return column which contain Dylan Dog Craven Road rows.

 

Capture

Import-Csv "C:\1.csv" | Select-Object  @{n='ResourceName';e={$_.FIRST_NAME + "," + $_.LAST_NAME + "," + $_.ADDRESS}} `
| Where-Object {$_.ResourceName -like "Dylan*Dog*Craven Road 7"}

Result:

ResourceName
------------------
Dylan,Dog,Craven Road 7

Recently i got long list of linux machines and had to check which of them support password authentication.

I found a tool Hydra , if it finds machine which do not support password authentication, it will print it in output

Hydra v8.2-dev (c) 2016 by van Hauser/THC - Please do not use in military
or secret service organizations, or for illegal purposes. Hydra
(http://www.thc.org/thc-hydra) starting at 2019-11-25 14:49:59 [DATA]
max 4 tasks per 4 servers, overall 64 tasks, 5 login tries (l:1/p:5),
~0 tries

per task [DATA] attacking service ssh on port 22
[ERROR] target ssh://1.1.1.1:22/ does not support password authentication.
[ERROR] target ssh://2.2.2.2:22/ does not support password authentication.

ERROR] target ssh://3.3.3.3:22/ does not support password authentication.

[ERROR] target ssh://4.4.4.4:22/ does not support password authentication.

4 of 4 targets completed, 0 valid passwords found Hydra 

(http://www.thc.org/thc-hydra) finished at 2019-11-25 14:50:01

So i created simple batch script which captures Hydra output into $command variable, then get string between [ERROR] target ssh:// and :22/ does not support into $out variable.

Then get IP address of masines – $filtered variable. Then print every IP into new line and write it to output.txt file.

Installing hydra (CentOS 7)

rpm -Uvh http://www6.atomicorp.com/channels/atomic/centos/7/x86_64/RPMS/atomic-release-1.0-21.art.noarch.rpm
yum install hydra

Put all your passwords to file pws.txt and machines IP into targets.txt

file: put every password/IP into new line

command=$((hydra -l root -P pws.txt -M targets.txt ssh -t 4) 2>&1)
echo $command
out=$(echo $command | grep -oP '(?<=ERROR] target ssh://).*(?=:22/ does not support)')
filtered=$(echo "$out" | sed 's|does not support password authentication.||g ; s|/||g ; s|ERROR||g ; s|target ssh||g ; s|:22||g ; s/[][]//g ; s|/||g ; s|:||g')
echo $filtered | xargs -n1 > output.txt

output.txt will contain IPs of machine which don’t support password authentication.

Let’s presume we have some PowerShell script for editing DNS entry, and we need to run it as Scheduled Task under some service account .

Add service account “Log on As Batch Job” right by using GPO:

  • Click START and type Group Policy then click on Group Policy ManagementEither edit the existing GPO that contains existing USER RIGHTS ASSIGNMENT (likely Default Domain Policy) or right click and CREATE AND EDIT a new policy
  • Expand Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > User Rights Assignment node
  • Double click Log on as a batch job
  • Click the Add User or Group button and add your service account user

1.PNG

In case you still get “This Task Requires That The User Account Specified Has Log On As Batch Job Rights” warning in task scheduler, add user to Backup Operators group.

Then add user to DNSAdmins group.

If script needs to be executed from remote machine:

Enabling Remote Management

  • add service account to WinRMRemoteWMIUsers__ on the DNS Server/DC.
  • On the Windows desktop, right-click Windows PowerShell on the taskbar, and then click Run as Administrator.
  • On the Windows start screen, right-click Windows PowerShell, and then on the app bar, click Run as Administrator.
  • type the following, and then press Enter to enable all required firewall rule exceptions.

Configure-SMremoting.exe -enable

 

Open Computer Management: start > run > compmgmt.msc

Expand Services and Applications – right click WMI Control – Properties – Security tab – click Security

2.png

Add service account

In the applies to, choose “this namespace and subnamespace” and Click “Allow” for Execute Methods and Enable Account.

If script needs to be run remotely, click “Allow” also for Remote Enable

3.png

For remote access:

In WMI Control expand root – cimv2 – Security

cimv2.png

Add the group WinRMRemoteWMIUsers__ as the principal, then click ok.

In the applies to, choose “this namespace and subnamespace”

Add service account and Click “Allow” for Execute Methods, Enable Account and Enable Remote

Restart Windows Management Instrumentation service

This script will ping IP 1.1.1.1, if ping fails, and if ping to 2.2.2.2 is successful, and if there is host A record for IP 1.1.1.1,it will change DNS record to match 2.2.2.2

function Switch-IP {
    [CmdletBinding()]
    param (
    
    [Parameter(Mandatory=$true][string]$IP,[Parameter(Mandatory=$true][string] $newIP
        )
  
    $currentIP = $oldobj.RecordData | select IPv4Address
    if ($currentIP.IPv4Address.IPAddressToString -eq $IP) {
         
    $newobj = get-dnsserverresourcerecord -name "nagios" -zonename "test.local" -rrtype "A"
    $updateip = $newIP
    $newobj.recorddata.ipv4address=[System.Net.IPAddress]::parse($updateip)
    Set-dnsserverresourcerecord -newinputobject $newobj -OldInputObject $oldobj -zonename "test.local" -passthru > C:\dnsfailover.log
    add-content -path C:\dnsfailover.log -Value $(Get-Date)
    }
    }

 $IP = "1.1.1.1"
 $newIP = "2.2.2.2"
 
    if (-Not (test-connection $IP -Quiet -Count 1)) {
    if (test-connection $newIP -Quiet -Count 1) { 

    $oldobj = get-dnsserverresourcerecord -name "nagios" -zonename "test.local" -rrtype "A"
 
    $currentIP = $oldobj.RecordData | select IPv4Address
    if ($currentIP.IPv4Address.IPAddressToString -eq $IP) {
         
    Switch-IP $IP $newIP
      
    }
 
}}
 
 
elseif ((test-connection $newIP -Quiet -Count 1) -and (test-connection $IP -Quiet -Count 1)) {
 
  
    $oldobj = get-dnsserverresourcerecord -name "nagios" -zonename "test.local" -rrtype "A"
 
    $currentIP = $oldobj.RecordData | select IPv4Address
    if ($currentIP.IPv4Address.IPAddressToString -eq $newIP) {
       
    Switch-IP $newIP $IP    
        
  }
 }
 

Next example assumes that there are 2 DNS records with same name (nagios), one record has IP 1.1.1.1, and second one is 2.2.2.2.

If ping to 1.1.1.1 fails, and if there are 2 DNS entries for host nagios, remove DNS entry for IP 1.1.1.1. When connection is restored, add back DNS entry for 1.1.1.1

$dnszone = "test.local"
$currentRecord = Get-DnsServerResourceRecord -name "nagios" -ZoneName $dnszone -RRType A 
$currentIP = $currentRecord.RecordData | select IPv4Address
$primaryIP = "1.1.1.1"
$secondaryIP = "2.2.2.2"    
    
    if (-Not (test-connection $primaryIP -Quiet -Count 1)) {
 
       if (test-connection $secondaryIP -Quiet -Count 1) { 
 
 
             if ($currentIP.Count -eq 2)  {
 
          try {
 
         Remove-DnsServerResourceRecord -name "nagios" -ZoneName $dnszone -RRType A -RecordData $primaryIP -Force -ErrorAction Stop -PassThru  > C:\dnsfailover.log  
         add-content -path C:\dnsfailover.log -Value "$(Get-Date):DNS entry removed" 
            }
 
          catch { 
          $Error[0].Exception.Message
                 }
 
 
    }}}
 
 
 
    elseif ((test-connection $secondaryIP -Quiet -Count 1) -and (test-connection $primaryIP -Quiet -Count 1)) {
 
  
           $currentRecord = Get-DnsServerResourceRecord -name "nagios" -ZoneName $dnszone -RRType A 
           $currentIP = $currentRecord.RecordData | select IPv4Address
    
        if  ($currentIP.Count -ne 2) {
 
        try {
 
         Add-DnsServerResourceRecord -A -Name "nagios" -ZoneName $dnszone -IPv4Address $primaryIP -TimeToLive 00:00:10 -PassThru  > C:\dnsfailover.log  
         add-content -path C:\dnsfailover.log -Value "$(Get-Date):DNS entry added" 
         }
 
         catch {
         $Error[0].Exception.Message
              }
       
      
  }
  
}

Following script will loop through all Partner Center customers, will export them in batches of 100 and every “chunk” will be exported to separate CSV file.

 

$custIDs = Get-PartnerCustomer
$chunks = [System.Collections.ArrayList]::new()
for ($i = 0; $i -lt $custIDs.Count; $i += 100) {
    if (($custIDs.Count - $i) -gt 99  ) {
        $chunks.add($custIDs[$i..($i + 99)])
    }
    else {
        $chunks.add($custIDs[$i..($custIDs.Count - 1)])
    }
}
$today = [datetime]::Today.ToString("yyyy-MM-dd")
$count = 1
foreach ($chunk in $chunks) {
    $path = "c:\Reports\$today Chunk $count of $($chunks.Count).csv"
    $chunk | Export-Csv $path -Append
    $count++
}