Ansible: Concatenate registered variable with string - amazon-web-services

I have this :
# grab the internal ip [eg 10.5.20.2]
- name: Grab the internal ip to setup the sec group rule
local_action: shell /sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1 # returns the ip
register: internal_ip # save the output of the above command in a var
- debug: var=internal_ip.stdout
I want to set this IP in the inbound rule of an AWS security group as single host IP.
Like this: 10.5.20.2/32
How do I concatenate the internal_ip registered var with the string /32 ??

I scratched and bled but found it... :]
"{{ internal_ip.stdout }}/32"

Related

indexing output of linux command in c++

I want to get the ip address given url.
I am currently using this
std::string i;
std::string pingStr = (std::string)"nslookup " +"www.yahoo.com" ;
i = system (pingStr.c_str());
but the output is
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
www.yahoo.com canonical name = atsv2-fp-shed.wg1.b.yahoo.com.
Name: atsv2-fp-shed.wg1.b.yahoo.com
Address: 106.10.250.10
Q: Is there anyway I can only get the Ip address?
Use the getaddrinfo(3) function to look up IP addresses, IPv4 or IPv6, in usable form.
you can use the folowing command.
nslookup www.yahoo.com | grep Address: | sed -n 2p
grep Address gives you all lines having "address" word in them
sed gets the 2nd line of those 2
You can truncate the "Address" part of output in c++.

AWS cloud-config not setting dns-nameservers

Here is the cloud.cfg on my instance (I had tampered it manually when provisioning the ami from which I launched the instance)
root#ip-10-17-0-121:~# cat /etc/cloud/cloud.cfg | grep -i resol -C 3
# Network configuration for ami
manage_resolv_conf: true
resolv_conf:
nameservers: ['10.11.4.1']
However this is never taken into account given that:
# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 10.17.0.2
search eu-west-1.compute.internal
I have tried with and without creating the following file
# cat /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
network: {config: disabled}
I managed to make my instance obtain my custom dns-nameserver as follows
- name: pre_tasks --> Add my custom dns-nameserver
lineinfile:
path: /etc/dhcp/dhclient.conf
regexp: '^#prepend domain-name-servers'
line: 'prepend domain-name-servers 10.11.4.1;'
become: yes
However now I am getting the following warning:
pkara#ip-10-17-0-35:~$ sudo -i
sudo: unable to resolve host ip-10-17-0-35
not accepting my answer until / unless I address this;
edit_1: adding this to my cloud-config.yml which I am setting as user data did not help much:
hostname: localhost
manage_etc_hosts: true
edit_2: adding this to my cloud-config.cfg helped me to address the above unable to resolve host problemn
bootcmd:
- echo "127.0.0.1 $(hostname)" >> /etc/hosts

how to use AWS instance's IP address dynamically in an ansible playbook without saving it in an external file using ansible playbook

I have 2 clusters, 1 of Cassandra(4 node cluster) and other of Kafka(3 node cluster) on EC2. I have a playbook which deploys my microservices on AWS instances, for that microservice playbook i have maintained an inventory file which stores my cassandra/kafka host's IP adresses in a variable as follows:
cassandra_hosts = 'X.X.X.X:9042,X.X.X.X:9042,X.X.X.X:9042,X.X.X.X:9042'
kafka_host = 'X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092'
The microservice playbook is somewhat as follows:
- hosts: dynamic_hosts
become: yes
become_user: xxxxxx
become_method: sudo
vars:
ansible_connection: "{{ connection_type }}"
ansible_ssh_user: "{{ ssh_user_name }}"
ansible_ssh_private_key_file: "{{ ssh_private_key_file }}"
tasks:
- name: Register Service as an Upstart
shell: chdir="{{dest_location}}" "./{{upstartscript}}.sh" " -p {{service_port}} -u {{service_uri}} -v {{service_version}} -c {{cassandra_hosts}} -k {{kafka_host}} -l {{log_level}}"
register: escript
- name: Register Service as an Upstart Output
debug:
msg : "{{ escript.stdout }}"
The code above is the way in which I retrieve the IP Address which i have hardcoded in the inventory file(mentioned in the first part of the code).
What I am trying to achieve is, how can I store the IP addresses of my AWS instances dynamically in my playbook and use it in my microservices playbook without storing the IP addresses in the inventory file, any suggestions
P.S. I request you to ask any question if needed, this is my first question here, Thanks in advance
Hi,
I also need to get the output of the kafka cluster, but kafka cluster outputs it in the AWS console in a different way as follows:
||| Outputs
|||
||+---------------------------+-----------------+---------------------------
----------------------------------------------------+||
||| Description | OutputKey |
OutputValue |||
||+---------------------------+-----------------+---------------------------
----------------------------------------------------+||
||| IP of Primary Seed Node | ZookeeperLink |
X.X.X.X:2181,X.X.X.X:2181,X.X.X.X:2181,X.X.X.X:2181
|||
||| IP of Primary Seed Node | Node2DNSName | ip-X-X-X-
X.ec2.internal |||
||| IP of Primary Seed Node | KafkaLink |
X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092
|||
||| IP of Primary Seed Node | Node3DNSName | ip-X-X-X-
X.ec2.internal |||
||| IP of Primary Seed Node | Node4DNSName | ip-X-X-X-
X.ec2.internal |||
||| IP of Primary Seed Node | Node1DNSName | ip-X-X-X-
X.ec2.internal
I just want to ouput the IPs of the part KafkaLink, any help on this:
X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092
I tried the following command but it is not working:
aws cloudformation describe-stacks --stack-name IngKafkaCluster --query 'Stacks[].Outputs[].OutputValue' --output text
I get the following ouput on the above command , which is not wrong but not exactly what i want:
X.X.X.X:2181,X.X.X.X:2181,X.X.X.X:2181,X.X.X.X:2181 ip-X-X-X-X.ec2.internal X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092,X.X.X.X:9092 ip-X-X-X-X.ec2.internal ip-X-X-X-X.ec2.internal ip-X-X-X-X.ec2.internal
For getting the AWS EC2's Ip addresses you can try the following command which will fetch the AWS output to a file you desire:
aws cloudformation describe-stacks --stack-name IngCassandraCluster --query 'Stacks[].Outputs[].OutputValue' --output text --> kunaltest.text
you can add this line in your playbook under :shell:" to make it do what you want.

How to find Unused Amazon EC2 Security groups

I'm try to find a way to determine orphan security groups so I can clean up and get rid of them. Does anyone know of a way to discover unused security groups.
Either through the console or with the command line tools will work (Running command line tools on linux and OSX machines).
Note: this only considers security use in EC2, not other services like RDS. You'll need to do more work to include security groups used outside EC2. The good thing is you can't easily (might not even be possible) to delete active security groups if you miss one associated w/another service.
Using the newer AWS CLI tool, I found an easy way to get what I need:
First, get a list of all security groups
aws ec2 describe-security-groups --query 'SecurityGroups[*].GroupId' --output text | tr '\t' '\n'
Then get all security groups tied to an instance, then piped to sort then uniq:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text | tr '\t' '\n' | sort | uniq
Then put it together and compare the 2 lists and see what's not being used from the master list:
comm -23 <(aws ec2 describe-security-groups --query 'SecurityGroups[*].GroupId' --output text | tr '\t' '\n'| sort) <(aws ec2 describe-instances --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text | tr '\t' '\n' | sort | uniq)
If you select all of your security groups in the EC2 console, then press actions -> Delete Security Groups, a popup will appear telling you that you cannot delete security groups that are attached to instances, other security groups, or network interfaces, and it will list the security groups that you can delete; ie the unused security groups.
NOTE: according to #andrewlorien’s comment this does not work for all types of AWS services.
This is the sample code written in boto (Python SDK for AWS) to list the Security Group against number of instances it is associated with.
You may use this logic to obtain the same in command line as well
Boto Code
import boto
ec2 = boto.connect_ec2()
sgs = ec2.get_all_security_groups()
for sg in sgs:
print sg.name, len(sg.instances())
Output
Security-Group-1 0
Security-Group-2 1
Security-Group-3 0
Security-Group-4 3
After about a year of unaudited use, I found it necessary to audit my AWS EC2 security groups and clean up legacy, unused groups.
This was a daunting task to perform via the web GUI, so I looked to the AWS CLI to make the task easier. I found a start on how to do this at StackOverflow, but it was far from complete. So I decided to write my own script. I used the AWS CLI, MySQL and some “Bash-foo” to perform the following:
Get a list of all EC2 security groups.
I store the group-id, group-name and description in a tabled called “groups” in a MySQL database called aws_security_groups on the localhost. The total number of groups found is reported to the user.
Get a list of all security groups associated with each of the following services and exclude them from the table:
EC2 Istances
EC2 Elastic Load Balancers
AWS RDS Instances
AWS OpsWorks (shouldn’t be removed per Amazon)
Default security groups (Can’t be deleted)
ElastiCache
For each service I report a count of the number of groups left in the table after the exclusion is complete.
Finally I display the group-id, group-name and description for the groups that are left. These are the “unused” groups that need to be audited and/or deleted. I’ve found that SG’s between instances and Elastic Load Balancers (ELBs) often refer to each other. It’s best practice to do some manual investigation to ensure they are truly not in use prior to removing the cross references and deleting the security groups. But my script at least pares this down to something mor manageable.
NOTES:
1. You will want to create a file to store your MySQL host, username and password and point the $DBCONFIG variable to it. It should be structured like this:
[mysql]
host=your-mysql-server-host.com
user=your-mysql-user
password=your-mysql-user-password
You can change the name of the database if you wish – make sure to change the $DB variable in the script
Let me know if you find this useful or have any comments,fixes or enhancements.
Here is the script.
#!/bin/bash
# Initialize Variables
DBCONFIG="--defaults-file=mysql-defaults.cnf"
DB="aws_security_groups"
SGLOOP=0
EC2LOOP=0
ELBLOOP=0
RDSLOOP=0
DEFAULTLOOP=0
OPSLOOP=0
CACHELOOP=0
DEL_GROUP=""
# Function to report back # of rows
function Rows {
ROWS=`echo "select count(*) from groups" | mysql $DBCONFIG --skip-column-names $DB`
# echo -e "Excluding $1 Security Groups.\nGroups Left to audit: "$ROWS
echo -e $ROWS" groups left after Excluding $1 Security Groups."
}
# Empty the table
echo -e "delete from groups where groupid is not null" | mysql $DBCONFIG $DB
# Get all Security Groups
aws ec2 describe-security-groups --query "SecurityGroups[*].[GroupId,GroupName,Description]" --output text > /tmp/security_group_audit.txt
while IFS=$'\t' read -r -a myArray
do
if [ $SGLOOP -eq 0 ];
then
VALUES="(\""${myArray[0]}"\",\""${myArray[1]}"\",\""${myArray[2]}"\")"
else
VALUES=$VALUES",(\""${myArray[0]}"\",\""${myArray[1]}"\",\""${myArray[2]}"\")"
fi
let SGLOOP="$SGLOOP + 1"
done < /tmp/security_group_audit.txt
echo -e "insert into groups (groupid, groupname, description) values $VALUES" | mysql $DBCONFIG $DB
echo -e $SGLOOP" security groups total."
# Exclude Security Groups assigned to Instances
for groupId in `aws ec2 describe-instances --output json | jq -r ".Reservations[].Instances[].SecurityGroups[].GroupId" | sort | uniq`
do
if [ $EC2LOOP -eq 0 ];
then
DEL_GROUP="'$groupId'"
else
DEL_GROUP=$DEL_GROUP",'$groupId'"
fi
let EC2LOOP="$EC2LOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "EC2 Instance"
DEL_GROUP=""
# Exclude groups assigned to Elastic Load Balancers
for elbGroupId in `aws elb describe-load-balancers --output json | jq -c -r ".LoadBalancerDescriptions[].SecurityGroups" | tr -d "\"[]\"" | sort | uniq`
do
if [ $ELBLOOP -eq 0 ];
then
DEL_GROUP="'$elbGroupId'"
else
DEL_GROUP=$DEL_GROUP",'$elbGroupId'"
fi
let ELBLOOP="$ELBLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "Elastic Load Balancer"
DEL_GROUP=""
# Exclude groups assigned to RDS
for RdsGroupId in `aws rds describe-db-instances --output json | jq -c -r ".DBInstances[].VpcSecurityGroups[].VpcSecurityGroupId" | sort | uniq`
do
if [ $RDSLOOP -eq 0 ];
then
DEL_GROUP="'$RdsGroupId'"
else
DEL_GROUP=$DEL_GROUP",'$RdsGroupId'"
fi
let RDSLOOP="$RDSLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "RDS Instances"
DEL_GROUP=""
# Exclude groups assigned to OpsWorks
for OpsGroupId in `echo -e "select groupid from groups where groupname like \"AWS-OpsWorks%\"" | mysql $DBCONFIG $DB`
do
if [ $OPSLOOP -eq 0 ];
then
DEL_GROUP="'$OpsGroupId'"
else
DEL_GROUP=$DEL_GROUP",'$OpsGroupId'"
fi
let OPSLOOP="$OPSLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "OpsWorks"
DEL_GROUP=""
# Exclude default groups (can't be deleted)
for DefaultGroupId in `echo -e "select groupid from groups where groupname like \"default%\"" | mysql $DBCONFIG $DB`
do
if [ $DEFAULTLOOP -eq 0 ];
then
DEL_GROUP="'$DefaultGroupId'"
else
DEL_GROUP=$DEL_GROUP",'$DefaultGroupId'"
fi
let DEFAULTLOOP="$DEFAULTLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "Default"
DEL_GROUP=""
# Exclude Elasticache groups
for CacheGroupId in `aws elasticache describe-cache-clusters --output json | jq -r ".CacheClusters[].SecurityGroups[].SecurityGroupId" | sort | uniq`
do
if [ $CACHELOOP -eq 0 ];
then
DEL_GROUP="'$CacheGroupId'"
else
DEL_GROUP=$DEL_GROUP",'$CacheGroupId'"
fi
let CACHELOOP="$CACHELOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "ElastiCache"
# Display Security Groups left to audit / delete
echo "select * from groups order by groupid" | mysql $DBCONFIG $DB | sed 's/groupid\t/groupid\t\t/'
And here is the sql to create the database.
-- MySQL dump 10.13 Distrib 5.5.41, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: aws_security_groups
-- ------------------------------------------------------
-- Server version 5.5.40-log
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET #OLD_TIME_ZONE=##TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `groups`
--
DROP TABLE IF EXISTS `groups`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `groups` (
`groupid` varchar(12) DEFAULT NULL,
`groupname` varchar(200) DEFAULT NULL,
`description` varchar(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = #saved_cs_client */;
--
-- Dumping data for table `groups`
--
LOCK TABLES `groups` WRITE;
/*!40000 ALTER TABLE `groups` DISABLE KEYS */;
/*!40000 ALTER TABLE `groups` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=#OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=#OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=#OLD_SQL_NOTES */;
-- Dump completed on 2015-01-27 16:07:44
Among other functions, both ScoutSuite and Prowler report unused EC2 Security Groups. Both are open source.
A boto example printing the Group IDs and Names only of the security groups that have no current instances.
It also shows how to specify which region you are concerned with.
import boto
import boto.ec2
EC2_REGION='ap-southeast-2'
ec2region = boto.ec2.get_region(EC2_REGION)
ec2 = boto.connect_ec2(region=ec2region)
sgs = ec2.get_all_security_groups()
for sg in sgs:
if len(sg.instances()) == 0:
print ("{0}\t{1}".format(sg.id, sg.name))
To confirm which security groups are still being used you should reverse or remove the if len(sg.instances()) == 0 test and print the len(sg.instances()) value out.
E.g.
print ("{0}\t{1}\t{2} instances".format(sg.id, sg.name, len(sg.instances())))
Using the node.js AWS SDK I can confirm that AWS doesn't allow you to delete security groups that are in use. I wrote a script that simply tries to delete all groups and gracefully handles the errors. This works for classic and the modern VPC. The error message can be seen below.
Err { [DependencyViolation: resource sg-12345678 has a dependent object]
message: 'resource sg-12345678 has a dependent object',
code: 'DependencyViolation',
time: Mon Dec 07 2015 12:12:43 GMT-0500 (EST),
statusCode: 400,
retryable: false,
retryDelay: 30 }
To the SGs attached to the network interfaces:
By name:
aws ec2 describe-network-interfaces --output text --query NetworkInterfaces[*].Groups[*].GroupName | tr -d '\r' | tr "\t" "\n" | sort | uniq
By id:
aws ec2 describe-network-interfaces --output text --query NetworkInterfaces[*].Groups[*].GroupId | tr -d '\r' | tr "\t" "\n" | sort | uniq
I was searching for the same info.
How to find all security groups that are not attached to any resource? And I found this:
Using AWS config rule "EC2_SECURITY_GROUP_ATTACHED_TO_ENI," I got a list of checks that non-default security groups are attached to Amazon Elastic Compute Cloud (EC2) instances or elastic network interfaces (ENIs). The rule returns NON_COMPLIANT if the security group is not associated with an EC2 instance or an ENI.
This is a very old question and I'm sure there are more ways to skin this AWS cat, but here's my solution in bash (you'll need jq for this to work):
REGION="eu-west-1"
SGLIST=$(aws ec2 describe-security-groups --query 'SecurityGroups[*].GroupId' | jq -r .[])
echo $SGLIST | xargs -n1 | while read SG; do [ "$(aws ec2 describe-network-interfaces --filters Name=group-id,Values=$SG --region $REGION | jq .NetworkInterfaces)" != '[]' ] || echo $SG; done
Remember to replace REGION with whatever region you're using.
The 1st step is to get a list of security groups.
Then we're checking for each security group if there's a network interface associated with it - this is not limited to EC2 instances, it checks anything that has a network interface (LBs, RDS, etc).
For reference see here.
Unfortunately the chosen answer is not as accurate as I need (I've tried to investigate the why, but I've preferred to implement it).
If I check ALL NetworkInterfaces, looking for attachments to any SecurityGroup, It gets me partial results. If I check only on EC2Instances, it gets me back partial results as well.
So that's my approach to the problem:
I get ALL EC2 SecurityGroups -> all_secgrp
I get ALL EC2 Instances -> all_instances
For each Instance, I get all SecurityGroups attached to it
I remove from all_secgrp each of these SecurityGroup (because attached)
For each SecurityGroup, I check an association with any NetworkInterfaces (using the filter function and filtering using that security-group-id)
IF no association is found, I remove the security-group from all_secgrp
Attached you can see a snippet of code. Don't complain for efficiency, but try to optimize it if you want.
all_secgrp = list(ec2_connector.security_groups.all())
all_instances = ec2_connector.instances.all()
for single_instance in all_instances:
instance_secgrp = ec2_connector.Instance(single_instance.id).security_groups
for single_sec_grp in instance_secgrp:
if ec2.SecurityGroup(id=single_sec_grp['GroupId']) in all_secgrp:
all_secgrp.remove(ec2.SecurityGroup(id=single_sec_grp['GroupId']))
all_secgrp_detached_tmp = all_secgrp[:]
for single_secgrp in all_secgrp_detached_tmp:
try:
print(single_secgrp.id)
if len(list(ec2_connector.network_interfaces.filter(Filters=[{'Name': 'group-id', 'Values': [single_secgrp.id]}]))) > 0:
all_secgrp.remove(single_secgrp)
except Exception:
all_secgrp.remove(single_secgrp)
return all_secgrp_detached
There's a tool in the AWS marketplace that makes this a lot easier. It shows you which groups are attached/detached for easy deletion, but it also compares your VPC Flow Logs against the security group rules and shows you which SG rules are in use or unused. AWS posted an ELK-stack solution to do this, but it was ridiculously complex.
Here's the tool, and a disclaimer that I worked on it. But I hope you all find it pertinent:
https://www.piasoftware.net/single-post/2018/04/24/VIDEO-Watch-as-we-clean-up-EC2-security-groups-in-just-a-few-minutes
This is a difficult problem, if you have security groups that reference other security groups in the rules. If so, you'll have to resolve DependencyErrors, which is not trivial.
If you are only using IP addresses, then this solution will work, after you create a boto3 client:
# pull all security groups from all vpcs in the given profile and region and save as a set
all_sgs = {sg['GroupId'] for sg in client.describe_security_groups()['SecurityGroups']}
# create a new set for all of the security groups that are currently in use
in_use = set()
# cycle through the ENIs and add all found security groups to the in_use set
for eni in client.describe_network_interfaces()['NetworkInterfaces']:
for group in eni['Groups']:
in_use.add(group['GroupId'])
unused_security_groups = all_sgs - in_use
for security_group in unused_security_groups:
try:
response = client.delete_security_group(GroupId=security_group)
except ClientError as e:
if e.response['Error']['Code'] == 'DependencyViolation':
print('EC2/Security Group Dependencies Exist')
else:
print('Unexpected error: {}'.format(e))

Bash Script: sed/awk/regex to match an IP address and replace

I have a string in a bash script that contains a line of a log entry such as this:
Oct 24 12:37:45 10.224.0.2/10.224.0.2 14671: Oct 24 2012 12:37:44.583 BST: %SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: root] [Source: 10.224.0.58] [localport: 22] [Reason: Login Authentication Failed] at 12:37:44 BST Wed Oct 24 2012
To clarify; the first IP listed there "10.224.0.2" was the machine the submitted this log entry, of a failed login attempt. Someone tried to log in, and failed, from the machine at the 2nd IP address in the log entry, "10.224.0.58".
I wish to replace the first occurrence of the IP address "10.224.0.2" with the host name of that machine, as you can see presently is is "IPADDRESS/IPADDRESS" which is useless having the same info twice. So here, I would like to grep (or similar) out the first IP and then pass it to something like the host command to get the reverse host and replace it in the log output.
I would like to repeat this for the 2nd IP "10.224.0.58". I would like to find this IP and also replace it with the host name.
It's not just those two specific IP address though, any IP address. So I want to search for 4 integers between 1 and 3, separated by 3 full stops '.'
Is regex the way forward here, or is that over complicating the issue?
Many thanks.
Replace a fixed IP address with a host name:
$ cat log | sed -r 's/10\.224\.0\.2/example.com/g'
Replace all IP addresses with a host name:
$ cat log | sed -r 's/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/example.com/g'
If you want to call an external program, it's easy to do that using Perl (just replace host with your lookup tool):
$ cat log | perl -pe 's/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/`host \1`/ge'
Hopefully this is enough to get you started.
There's variou ways to find th IP addresses, here's one. Just replace "printf '<<<%s>>>' " with "host" or whatever your command name is in this GNU awk script:
$ cat tst.awk
{
subIp = gensub(/\/.*$/,"","",$4)
srcIp = gensub(/.*\[Source: ([^]]+)\].*/,"\\1","")
"printf '<<<%s>>>' " subIp | getline subName
"printf '<<<%s>>>' " srcIp | getline srcName
gsub(subIp,subName)
gsub(srcIp,srcName)
print
}
$
$ gawk -f tst.awk file
Oct 24 12:37:45 <<<10.224.0.2>>>/<<<10.224.0.2>>> 14671: Oct 24 2012 12:37:44.583 BST: %SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: root] [Source: <<<10.224.0.58>>>] [localport: 22] [Reason: Login Authentication Failed] at 12:37:44 BST Wed Oct 24 2012
googled this one line command together. but was unable to pass the founded ip address to the ssh command:
sed -n 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/\nip&\n/gp' test | grep ip | sed 's/ip//' | sort | uniq
the "test" is the file the sed command is searching for for the pattern