Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts
, , ,

Enable Root Login via SSH In Ubuntu

 By default, SSH on Ubuntu comes configured in a way that disables the root users log in. This was originally enabled as a security precaution which means that you cannot directly log in as the root user over SSH. However, you can usually get around the need for root ssh login by using the sudo command. In some cases, though it’s just more convenient to get directly logged in as root.

Enable root login over SSH

  1. Login to your server as root.
  2. As the root user, edit the sshd_config file found in /etc/ssh/sshd_config:vim /etc/ssh/sshd_config
  3. Add the following line to the file, you can add it anywhere but it’s good practice to find the block about authentication and add it there.
    PermitRootLogin yes
  4. Save and exit the file.
  5. Restart the SSH server:
    systemctl restart sshd
    or
    service sshd restart

And that’s it! With the new line added and the SSH server restarted, you can now connect via the root user.

In this instance, you are going to be able to login as the root user utilizing either the password or an ssh key.

When using SSH Keys, you can set the PermitRootLogin value to `without-password` instead of yes. To accomplish this, simply modify the following information noted in step 2 above instead:

PermitRootLogin without-password

This process should work on almost any version of Linux server that the sshd service is installed. If you are using a cPanel server though you can easily control this setting from the WHM interface. In these cases, it’s recommended to modify this setting from your control panel interface.




Continue reading Enable Root Login via SSH In Ubuntu
, ,

Issues with firewall on HW Node - Impossible to use ip_nat and ipt_state modules

Information

Symptoms vary and may include:
  • Some iptables rules are not working
  • You see the following error when trying to create an iptables rule in the NAT table or when trying to use the STATE module:
    # iptables -t nat -L
    iptables v1.3.5: can't initialize iptables table `nat': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded.
    #
    

Cause

This problem usually occurs because connection tracking (the "conntracks" module) is disabled on your Parallels Virtuozzo Containers (PVC) hardware node (HW Node) by default. This means iptables is not statefull in the default installation.
You can verify this by checking whether you get the same output as below:
~# grep conntrac /etc/modprobe.d/vz-parallels.conf
options nf_conntrack ip_conntrack_disable_ve0=1
When support for connection tracking is disabled, the NAT table is absent in the list of available tables:
~# cat /proc/net/ip_tables_names
mangle
filter
Therefore, it is impossible to use the nf_nat and xt_state modules on the HW Node.

Resolution

Note: STATE module functionality of iptables may be replaced by adding explicit complimentary rules for INPUT and OUTPUT chains.
If you are not satisfied by that workaround or if you need the NAT table functionality, continue reading further.
Before you enable connection tracking support, we strongly recommend considering the following notes and warnings:
Warning 1: Enabling connection tracking uses a lot of resources.
Warning 2: With "conntracks" enabled, the HW Node may become completely unreachable from the network when you have a high network load. If a hosted container has malicious software running, a kernel panic can occur.
That is because the number of connection tracking slots is limited for a physical server. Enabling "conntracks" is especially dangerous for a PVC HW Node, because it allocates two tracking slots for each connection to a container รข€“ one for external connection and another one for connecting the HW Node with the container. So if a container opens too many connections, the HW Node will not be able to create any new connections.
This sort of situation might arise due to a DDoS attack of any container. The HW Node administrator would not be able to stop it by stopping a CT or adding iptables rules, because the administrator could not log in to the Node.

How to enable "conntracks":

  1. Check that all necessary modules are loaded on the Hardware Node:
    ~# lsmod | grep -E "state|nat"
    nf_nat_ftp              3489  0
    nf_conntrack_ftp       12927  1 nf_nat_ftp
    iptable_nat             6236  0
    nf_nat                 23178  3 vzrst,nf_nat_ftp,iptable_nat
    nf_conntrack_ipv4       9848  3 iptable_nat,nf_nat
    ip_tables              18021  3 iptable_nat,iptable_mangle,iptable_filter
    xt_state                1474  2
    nf_conntrack           80758  8 vzrst,nf_nat_ftp,nf_conntrack_ftp,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
    
  2. Add those modules to the iptables configuration on the Node:
    ~# egrep '^IPTABLES_MODULES' /etc/sysconfig/iptables-config
    IPTABLES_MODULES="ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length xt_length xt_hl xt_tcpmss xt_TCPMSS xt_multiport xt_limit xt_dscp nf_conntrack iptable_nat"
    IPTABLES_MODULES_UNLOAD="yes"
    
  3. Edit /etc/modprobe.d/vz-parallels.conf and set ip_conntrack_disable_ve0=0:
    ~# grep conntrac /etc/modprobe.d/vz-parallels.conf
    options nf_conntrack ip_conntrack_disable_ve0=0
    
  4. Enable iptables, logging to verify that it works:
    ~# egrep '^kern' /etc/rsyslog.conf
    kern.*                                                 /var/log/messages
    
  5. Restart iptables:
    ~]# service iptables restart
    iptables: Applying firewall rules:                         [  OK  ]
    iptables: Loading additional modules: ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length xt_length xt_hl xt_tcpmss xt_TCPMSS xt_multiport xt_limit xt_dscp ip_conntrack iptable_nat                                         [  OK  ]
    
    (Please note that unloading of kernel modules can fail if modules are in use by running containers.)
  6. Restart syslog:
    ~# service rsyslog restart
    Shutting down system logger:                               [  OK  ]
    Starting system logger:                                    [  OK  ]
    
  7. Add a test rule, e.g., one to track new SSH connections:
    ~# iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name ssh_attempt --rsource -j LOG --log-prefix "SSH connection attempt: "
    
  8. Avoid tracking any other TCP connections to save system resources:
    ~# iptables -t raw -I PREROUTING -p tcp !  --dport 22 -j NOTRACK
    
    Note: setting rules in the raw table might cause issues with CT #1 restart. Update PVA Agent to the latest version.
  9. Try to log in to the server via SSH while monitoring the log:
    Jan 11 02:29:19 pvclin47 kernel: [  106.459592] SSH connection attempt: IN=eth0 OUT= MAC=00:1c:42:ac:d1:c9:00:1e:67:07:55:95:08:00 SRC=192.168.55.3 DST=10.39.3.111 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=44446 DF PROTO=TCP SPT=51889 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
    Jan 11 02:29:19 pvclin47 kernel: [  106.459592] SSH connection attempt: IN=eth0 OUT= MAC=00:1c:42:ac:d1:c9:00:1e:67:07:55:95:08:00 SRC=192.168.55.3 DST=10.39.3.111 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=44446 DF PROTO=TCP SPT=51889 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
    

FAQ

Q: What exactly does this option do?
A: This option controls the tracking of packets in the Node's environment. When it is disabled, packets are accepted, routed, etc., but the kernel does not store any information about the packet's connections, as it considers each packet to be a complete unit.
This option also has implications for NAT. For NAT, you need to have the following information: you need to determine the first packet of a connection and decide which of the next packets belongs to this first packet, i.e., which packet should be considered as a "connection."

Additional information

Continue reading Issues with firewall on HW Node - Impossible to use ip_nat and ipt_state modules
,

SSH Connection: Wait long after entering username – ssh password prompt delay

When I make ssh connection I get long wait just after entering username. It’s most likely that ssh daemon  is set up to do a DNS reverse-lookup on the host that’s connecting. So, sshd try to find reverse DNS record for a while before prompting you password.
If you do not want to wait,  you can either add your client’s ip and hostname information to /etc/hosts file on linux or you can disable reverse dns lookup in /etc/ssh/sshd_config
1- Open your terminal window
2- Edit /etc/ssh/sshd_config
3- Add UseDNS no at the end
4- Restart your ssh daemon
Continue reading SSH Connection: Wait long after entering username – ssh password prompt delay
, ,

Deny or allow countries with apache .htaccess

Introduction

The following script is using blogama.org IP geolocation API to automatically generate Apache .htaccess file to deny or allow specific countries. You can put this script under crontab and the .htaccess rules will be automatically updated. Also, it can update multiple .htaccess files.

Deny or allow?

First you need to understand the meaning of these two rules in the .htaccess file. If you set "deny" in the script for countries "US,CA" (USA and Canada), all traffic from USA or Canada will be blocked. On the other hand, if you set "allow" it will only accept traffic from these two countries, all others being blocked.

Countries code

You need to know the ISO country code you want to deny/allow. The list is available here.

Usage without the automated script

Where country is the list or countries, with a comma between them and output is either htaccess_deny or htaccess_allow.

How is the script working?

You will have to create a text file with all .htaccess files (with complete path) you wish to update with the script. If you have other information in your .htaccess files they will still remain there, the script will only update the portion between the tags "#COUNTRY_BLOCK_START" and "#COUNTRY_BLOCK_END".

Before you start with the script

Create a text file named htaccessfile.txt (in the WORKDIR of the script, see below). In that file, put all (existing!) .htaccess files you wish to update. For example:

/var/www/example.com/.htaccess
/var/www/mydomain.com/.htaccess

Script configuration

On top of the script, you will find this section. You need to modify these variables if needed:

###MODIFY THIS SECTION###
WORKDIR="/root/"
HTACCESSFILE="htaccessfile.txt"
HTACCESSBLOCK="htaccess-blocklist.txt"
TEMPFILE="htaccess.temp"
COUNTRIES="US,CA"
TYPE="allow"
#########################

WORKDIR: is a writable directory where the script will be located.
HTACCESSFILE: is the file where you will put your .htaccess paths.
HTACCESSBLOCK and TEMPFILE: are temporary file that will be deleted at the end of the script execution.
COUNTRIES: is the list of countries you wish to deny/allow, separated with a comma.
TYPE: "allow" or "deny" access to these countries.

The script

#!/bin/bash
###BLOGAMA.ORG###
###MODIFY THIS SECTION###
WORKDIR="/root/"
HTACCESSFILE="htaccessfile.txt"
HTACCESSBLOCK="htaccess-blocklist.txt"
TEMPFILE="htaccess.temp"
COUNTRIES="US,CA"
TYPE="deny"

#########################

#####DO NOT MAKE MODIFICATIONS BELOW#####

cd $WORKDIR
#Get the file from blogama.org API
wget -c --output-document=$HTACCESSBLOCK "http://blogama.org/country_query.php?country=$COUNTRIES&output=htaccess_$TYPE"
for i in $( cat $WORKDIR$HTACCESSFILE ); do
if [ -f $i ]; then
cat $i 2>&1 | grep "COUNTRY_BLOCK_START"
if [ "$?" -ne "1" ]; then #ALREADY IN HTACCESS
sed '/#COUNTRY_BLOCK_START/,/#COUNTRY_BLOCK_END/d' $i > $WORKDIR$TEMPFILE
cat $WORKDIR$HTACCESSBLOCK >> $WORKDIR$TEMPFILE
mv $WORKDIR$TEMPFILE $i
else #NOT IN HTACCESS
cat $WORKDIR$HTACCESSBLOCK >> $i
fi
fi
done
rm -f $WORKDIR$HTACCESSBLOCK
Make it executable:

chmod +x whatever_you_called_this_script

Add it to your crontab:

* * * * * /path/to/whatever_you_called_this_script >/dev/null 2>&1

Note: Use this script at your own risk.
Continue reading Deny or allow countries with apache .htaccess
,

A Sample syslog-ng conf file

################################################################################
# Syslog-ng configuration file. Revised, and rewrited by me (Shahjahan Siraj )
#
###############################################################
# First, set some global options.

options {
# use_fqdn(yes);
# use_dns(yes);
# dns_cache(yes);
keep_hostname(yes);
long_hostnames(off);
sync(1);
log_fifo_size(1024);
};

###############################################################
#
# This is the default behavior of sysklogd package
# Logs may come from unix stream, but not from another machine.
#
#source src { unix-stream("/dev/log"); internal(); };


source src {
# don't read from /proc/kmsg and run klogd also (Linux)
pipe("/proc/kmsg");
# file("/proc/kmsg") log_prefix("kernel: ");
unix-stream("/dev/log");
# unix-stream("/chroot/named/dev/log");
internal();
udp();
# udp(ip("10.0.5.8") port(514));
tcp(port(5140) keep-alive(yes));
# tcp(ip("10.9.9.3") port(5140) keep-alive(yes));
};


###############################################################
# After that set destinations.

# First some standard logfile
#
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination uucp { file("/var/log/uucp.log"); };


# This files are the log come from the mail subsystem.
#
destination mail { file("/var/log/mail.log"); };
destination maillog { file("/var/log/maillog"); };
destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

# Logging for INN news system
#
destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

# Some `catch-all' logfiles.
#
destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };

# The root's console.
#
destination console { usertty("root"); };

# Virtual console.
#
destination console_all { file("/dev/tty8"); };

# The named pipe /dev/xconsole is for the nsole' utility. To use it,
# you must invoke nsole' with the -file' option:
#
# $ xconsole -file /dev/xconsole [...]
#
destination xconsole { pipe("/dev/xconsole"); };

#
# scripts that accept syslog messages and mail them out
#
destination mail-alert { program("/usr/local/bin/syslog-mail"); };
destination mail-alert-perl { program("/usr/local/bin/syslog-mail-perl"); };

#
# hack to get swatch to read from stdin
#
destination swatch { program("/usr/bin/swatch --read-pipe=\"cat /dev/fd/0\""); };

#
# destination database
#
destination sqlsyslogd {
program("/usr/local/sbin/sqlsyslogd -u sqlsyslogd -t logs sqlsyslogd -p");
};

##########################################

# Here's the filter options. With this rules, we can set which
# message go where.

filter f_attack_alert {
match("attackalert");
};

filter f_ssh_login_attempt {
program("sshd.*")
and match("(Failed|Accepted)")
and not match("Accepted (hostbased|publickey) for (root|zoneaxfr) from (10.4.3.1)");
};

filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(auth, authpriv) and not facility(mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_uucp { facility(cron); };

filter f_news { facility(news); };

filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info .. warn)
and not facility(auth, authpriv, cron, daemon, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };

filter f_cnews { level(notice, err, crit) and facility(news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };

###############################################################
#
# log statements actually send logs somewhere, to a file, across the network, etc
#

#log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_authpriv); destination(syslog); };
log { source(src); filter(f_syslog); destination(syslog); };
#log { source(src); filter(f_cron); destination(cron); };
#log { source(src); filter(f_daemon); destination(daemon); };
log { source(src); filter(f_daemon); destination(messages); };
#log { source(src); filter(f_kern); destination(kern); };
log { source(src); filter(f_kern); destination(messages); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
#log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_user); destination(messages); };
log { source(src); filter(f_uucp); destination(uucp); };
log { source(src); filter(f_mail); destination(maillog); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };
log { source(src); filter(f_news); filter(f_crit); destination(newscrit); };
log { source(src); filter(f_news); filter(f_err); destination(newserr); };
log { source(src); filter(f_news); filter(f_notice); destination(newsnotice); };
#log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

#log { source(src); filter(f_cnews); destination(console_all); };
#log { source(src); filter(f_cother); destination(console_all); };

log { source(src); filter(f_cnews); destination(xconsole); };
log { source(src); filter(f_cother); destination(xconsole); };


# slap it into a MySQL database
log {
source(src);
destination(sqlsyslogd);
};

# find messages with "attackalert" in them, and send to the mail-alert script
log {
source(src);
filter(f_attack_alert);
destination(mail-alert-perl);
};

# find messages reporting attempted ssh logins, and send to the mail-alert script
log {
source(src);
filter(f_ssh_login_attempt);
destination(mail-alert-perl);
};

# send all logs to swatch for (near) real-time alerts
log {
source(src);
destination(swatch);
};


## set up logging to loghost
#destination loghost {
# tcp("10.0.0.1" port(514));
#};

# send everything to loghost, too
#log {
# source(src);
# destination(loghost);
#};

#
# automatic host sorting (usually used on a loghost)
#

# set it up
destination std {
file("/var/log/HOSTS/$HOST/$YEAR/$MONTH/$DAY/$FACILITY_$HOST_$YEAR_$MONTH_$DAY"
owner(root) group(root) perm(0600) dir_perm(0700) create_dirs(yes)
);
};

# log it
log {
source(src);
destination(std);
};

###############################################################
Continue reading A Sample syslog-ng conf file
,

Logging with syslog-ng

Managing Linux system and application logging is important and a bit tricky. You want to capture important information, not bales of noise. You need to be able to find what you want in your logs without making it your life's work. The venerable old syslogd has served nobly for many years, but it's not quite up to meeting more complex needs. For this we have the next-generation Linux logger, syslog-ng.

Syslog-ng has a number of advantages over syslogd: better networking support, highly-configurable filters, centralized network logging, and lots more flexibility. For example, with syslogd all iptables messages get dumped in kern.log along with all the other kernel messages. Syslog-ng lets you direct iptables messages to a separate logfile. Syslogd uses only UDP; syslog-ng runs over UDP and TCP, so you can run it over encrypted network tunnels to a central logging server.

Installation
Syslog-ng is a standard package on all Linuxes. The current stable release is 1.6. If you are using apt-get or yum sysklogd should be removed automatically. But if it isn't, make sure to remove it and to stop the syslogd daemon. (sysklogd is the package name, syslogd is the daemon.)

Configuration File Structure
With all of this flexibility comes a bit of a learning curve. Syslog-ng's configuration file is /etc/syslog-ng/syslog-ng.conf, or on some systems /etc/syslog-ng.conf. You'll need man 5 syslog-ng.conf to understand all the different options and parameters. syslog-ng.conf has five possible sections:

options{}
Global options. These can be overridden in any of the next four sections

source{}
Message sources, such as files, local sockets, or remote hosts

destination{}
Message destinations, such as files, local sockets, or remote hosts

filter{}
Filters are powerful and flexible; you can filter on any aspect of a log message, such as standard syslogd facility names (man 5 syslog.conf), log level, hostname, and arbitrary contents like words or number strings

log{}
Log statements connect the source, destination, and filter statements, and tell syslog-ng what to do with them

Here are some typical global options:

options {

sync (0);
log_fifo_size (2048);
create_dirs (yes);
group (logs);
dir_group (logs);
perm (0640);
dir_perm (0750);
};

Options statements must use options as defined in /etc/syslog-ng.conf. This what the examples mean:

sync
How many lines of messages to keep in the output queue before writing to disk. (Logging output is called "messages.") Zero is the preferred option, since you want to be sure to capture everything, and not risk losing data in the event of a power failure

log_fifo_size
The maximum number of lines of messages in the output queue. The default is 100 lines of messages. You can do some calculations to figure out a suitable value, as this syslog-ng mail list post shows. To quote the relevant bit:

Each message source receives maximum 1024 bytes of data. A single log message is about 20 to 30 bytes. So on a single run each log source may emit 1024/20 = 50 messages. Your log fifo must be able to hold this number of messages for each source. So for two sources, you'll need at least 100 slots in your fifo.

It is easy to get confused by these two options. Incoming messages from remote hosts arrive in bursts, so what you need to do is make sure your log_fifo_size is large enough to handle these bursts. Otherwise you risk losing messages. Ultimately you will be limited by i/o and network speeds

create_dirs
Enable or disable automatic directory creation for destination files. In this article this value is "yes", so that remote host directories can be created on demand

group
dir_group
Set the group owner of logfiles and directories, so you don't have to read and analyze logs as the superuser

perm
dir_perm
Default permissions on new files and directories

Source, Destination, and Filter Statements
Source, destination, and filter names are arbitrary, like these examples show:

source s_local { internal(); unix-stream("/dev/log"); file("/proc/kmsg" log_prefix("kernel: ")); };
destination d_auth { file("/var/log/auth.log"); };
filter f_auth { facility(auth, authpriv); };

So "source s_local" could be "source frederick_remington_depew" if you so desired, and "destination d_auth" could be "destination moon." The convention is to prefix source names with "s", destination names with "d", and filter names with "f", but this is not required. All other elements of source, destination, and filter statements must use parameters as defined in man 5 syslog-ng.conf.

The "source s_local" example collects all locally-generated log messages into a single source statement. The "destination d_auth" statement directs authorization messages to /var/log/auth.log, which are defined by the "filter f_auth" statement. auth and authpriv are standard syslog facility names.

Log statements pull it all together:

log {source(s_local); filter(f_auth); destination(d_auth); };

So these four lines filter out all the auth and authpriv messages from all local messages, and write them to /var/log/auth.log.

Enabling Remote Logging
While it's possible to send log messages from remote clients with good old syslogd, it's really not adequate because it only transmits UDP packets. So you need syslog-ng installed on all client hosts as well. Adding these lines to syslog-ng.conf on the server accepts remote messages from clients and dumps them into a single file per host:

source s_remote { tcp(); };
destination d_clients { file("/var/log/HOSTS/$HOST"); };
log { source(s_remote); destination(d_clients); };

This is a very simple, but functional example for your client hosts that collects all local messages and sends them to the remote server:

#sample syslog-ng.conf for a remote client
source s_local { internal(); unix-stream("/dev/log"); file("/proc/kmsg" log_prefix("kernel: ")); };
destination d_loghost {tcp("192.168.1.10" port(514));};
log { source(s_local); destination(loghost); };

Sample syslog-ng.conf
A complete sample configuration file is a bit long to include here, so you should take a look at the one that came with your syslog-ng installation. Debian users get a customized file that replicates a syslogd setup. Let's put together our examples here in a single file for the server, set up a remote client, and run some tests to see how it works:

#sample syslog-ng.conf for a central logging server
options {

sync (0);
log_fifo_size (2048);
create_dirs (yes);
group (logs);
dir_group (logs);
perm (0640);
dir_perm (0750);
};

source s_local { internal(); unix-stream("/dev/log"); file("/proc/kmsg" log_prefix("kernel: ")); };
destination d_auth { file("/var/log/auth.log"); };
filter f_auth { facility(auth, authpriv); };

source s_remote { tcp(); };
destination d_clients { file("/var/log/HOSTS/$HOST"); };

log { source(s_remote); destination(d_clients); };
log { source(s_local); filter(f_auth); destination(d_auth); };

Whenever you make changes to syslog-ng.conf you must restart it:

# /etc/init.d/syslog-ng restart

Testing Everything
Now you can runs some simple tests on both the server and the client. Since the only local server messages that are going to be logged are authorization messages, you can test these by opening a new login session on the server, or running su or sudo. Then check /var/log/auth.log. Test the client by doing anything, then see if a new directory was created for the remote client in /var/log/HOSTS.

Another way is to use the useful and excellent logger command:

# logger "this is a test"
# logger -p auth.debug "this is a test"

This will create a line like this in your logfiles:

Apr 1 16:08:42 localhost.localdomain logger: this is a test

Now that we have a grasp of syslog-ng basics, come back next week to learn how to fine-tune and organize syslog-ng just the way you like, for both local and remote logging, and how to securely encrypt all syslog-ng network transmissions.

Continue reading Logging with syslog-ng
,

Search for all account without password and lock them

For security, reason it is necessary to disable all account(s) with no password and lock them down. Solaris, Linux and FreeBSD provide account locking (unlocking) facility.

Lock Linux user account with the following command:

passwd -l {user-name}

Solaris UNIX display password status

passwd  -u {user-name}

-l : This option disables an account by changing the password to a value, which matches no possible encrypted value.

Lock FreeBSD user account with the following command:

pw lock {username}

FreeBSD unlocking the account use:

pw unlock {username}

Lock Solaris UNIX user account with the following command:

passwd -l {username}

Lock HP-UX user account with the following command:

passwd -l {username}

For unlocking the HP-UX account you need to edit /etc/passwd file using text editor (or use SAM):

vi /etc/passwd 

However, how will you find out account without password? Again, with the help of 'passwd -s' (status) command you can find out all passwordless accounts.

Linux display password status

passwd -S {user-name}

Where,
-S : Display account status information. The status information consists of total seven fields. The second field indicates the status of password using following format:

  • L : if the user account is locked (L)
  • NP : Account has no password (NP)
  • P: Account has a usable password (P)
# passwd -S radmin

radmin P 10/08/2005 0 99999 7 -1

Solaris UNIX display password status

passwd -s {user-name}

Where,
-s : Display account status information using following format:

  • PS : Account has a usable password
  • LK : User account is locked
  • NP : Account has no password

FreeBSD
I have already written about small awk one line approach to find out all passwords less accounts.

Automated Scripting Solution
However, in real life you write a script and execute it from cron job. Here is small script for Linux:

#!/bin/sh
USERS="$(cut -d: -f 1 /etc/passwd)"
for u in $USERS
do
passwd -S $u | grep -Ew "NP" >/dev/null
if [ $? -eq 0 ]; then
passwd -l $u
fi
done

FreeBSD script:

#!/bin/bash
USERS="$(awk -F: 'NF > 1 && $1 !~ /^[#+-]/ && $2=="" {print $0}'
/etc/master.passwd | cut -d: -f1)"
for u in $USERS
do
pw lock $u
done

Sun Solaris script:

#!/bin/sh
USERS=`passwd -sa | grep -w NP | awk '{ print $1 }'`
for u in $USERS
do
passwd -l $u
done

You can easily add email alert support to script so that when ever scripts finds passwordless account(s) it will send an email alert. See the complete working example of script here.

Continue reading Search for all account without password and lock them
,

A script to add user in Linux

# Path to files
pfile=/etc/passwd
gfile=/etc/group
sfile=/etc/shells

# Paths to binaries
useradd=/usr/sbin/useradd
chfn=/usr/bin/chfn
passwd=/usr/bin/passwd
chmod=/bin/chmod

# Defaults
defhome=/home
defshell=/bin/bash
defchmod=711 # home dir permissions - may be preferable to use 701, however.
defgroup=users
AGID="audio cdrom floppy plugdev video" # additional groups for desktop users

# Determine what the minimum UID is (for UID recycling)
# (we ignore it if it's not at the beginning of the line (i.e. commented out with #))
export recycleUIDMIN="$(grep ^UID_MIN /etc/login.defs | awk '{print $2}' 2>/dev/null)"
# If we couldn't find it, set it to the default of 1000
if [ -z "$recycleUIDMIN" ]; then
export recycleUIDMIN=1000
fi


# This setting enables the 'recycling' of older unused UIDs.
# When you userdel a user, it removes it from passwd and shadow but it will
# never get used again unless you specify it expliticly -- useradd (appears to) just
# look at the last line in passwd and increment the uid. I like the idea of
# recycling uids but you may have very good reasons not to (old forgotten
# confidential files still on the system could then be owned by this new user).
# We'll set this to no because this is what the original adduser shell script
# did and it's what users expect.
recycleuids=no

# Function to read keyboard input.
# bash1 is broken (even ash will take read -ep!), so we work around
# it (even though bash1 is no longer supported on Slackware).
function get_input() {
local output
if [ "`echo $BASH_VERSION | cut -b1`" = "1" ]; then
echo -n "${1} " >&2 # fudge for use with bash v1
read output
else # this should work with any other /bin/sh
read -ep "${1} " output
fi
echo $output
}

# Function to display the account info
function display () {
local goose
goose="$(echo $2 | cut -d ' ' -f 2-)" # lop off the prefixed argument useradd needs
echo -n "$1 "
# If it's null then display the 'other' information
if [ -z "$goose" -a ! -z "$3" ]; then
echo "$3"
else
echo "$goose"
fi
}

# Function to check whether groups exist in the /etc/group file
function check_group () {
local got_error group
if [ ! -z "$@" ]; then
for group in $@ ; do
local uid_not_named="" uid_not_num=""
grep -v "$^" $gfile | awk -F: '{print $1}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_named=yes
grep -v "$^" $gfile | awk -F: '{print $3}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_num=yes
if [ ! -z "$uid_not_named" -a ! -z "$uid_not_num" ]; then
echo "- Group '$group' does not exist"
got_error=yes
fi
done
fi
# Return exit code of 1 if at least one of the groups didn't exist
if [ ! -z "$got_error" ]; then
return 1
fi
}

#: Read the login name for the new user :#
#
# Remember that most Mail Transfer Agents are case independant, so having
# 'uSer' and 'user' may cause confusion/things to break. Because of this,
# useradd from shadow-4.0.3 no longer accepts usernames containing uppercase,
# and we must reject them, too.

# Set the login variable to the command line param
echo
LOGIN="$1"
needinput=yes
while [ ! -z $needinput ]; do
if [ -z "$LOGIN" ]; then
while [ -z "$LOGIN" ]; do LOGIN="$(get_input "Login name for new user []:")" ; done
fi
grep "^${LOGIN}:" $pfile >/dev/null 2>&1 # ensure it's not already used
if [ $? -eq 0 ]; then
echo "- User '$LOGIN' already exists; please choose another"
unset LOGIN
elif [ ! -z "$( echo $LOGIN | grep "^[0-9]" )" ]; then
echo "- User names cannot begin with a number; please choose another"
unset LOGIN
elif [ ! "$LOGIN" = "`echo $LOGIN | tr A-Z a-z`" ]; then # useradd does not allow uppercase
echo "- User '$LOGIN' contains illegal characters (uppercase); please choose another"
unset LOGIN
elif [ ! -z "$( echo $LOGIN | grep '\.' )" ]; then
echo "- User '$LOGIN' contains illegal characters (period/dot); please choose another"
unset LOGIN
else
unset needinput
fi
done

# Display the user name passed from the shell if it hasn't changed
if [ "$1" = "$LOGIN" ]; then
echo "Login name for new user: $LOGIN"
fi

#: Get the UID for the user & ensure it's not already in use :#
#
# Whilst we _can_ allow users with identical UIDs, it's not a 'good thing' because
# when you change password for the uid, it finds the first match in /etc/passwd
# which isn't necessarily the correct user
#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
_UID="$(get_input "User ID ('UID') [ defaults to next available ]:")"
grep -v "^$" $pfile | awk -F: '{print $3}' | grep "^${_UID}$" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "- That UID is already in use; please choose another"
elif [ ! -z "$(echo $_UID | egrep '[A-Za-z]')" ]; then
echo "- UIDs are numerics only"
else
unset needinput
fi
done
# If we were given a UID, then syntax up the variable to pass to useradd
if [ ! -z "$_UID" ]; then
U_ID="-u ${_UID}"
else
# Will we be recycling UIDs?
if [ "$recycleuids" = "yes" ]; then
U_ID="-u $(awk -F: '{uid[$3]=1} END { for (i=ENVIRON["recycleUIDMIN"];i in uid;i++);print i}' $pfile)"
fi
fi

#: Get the initial group for the user & ensure it exists :#
#
# We check /etc/group for both the text version and the group ID number
echo
needinput=yes
while [ ! -z "$needinput" ]; do
GID="$(get_input "Initial group [ ${defgroup} ]:")"
check_group "$GID"
if [ $? -gt 0 ]; then
echo "- Please choose another"
else
unset needinput
fi
done
# Syntax the variable ready for useradd
if [ -z "$GID" ]; then
GID="-g ${defgroup}"
else
GID="-g ${GID}"
fi

#: Get additional groups for the user :#
#
echo "Additional UNIX groups:"
echo
echo "Users can belong to additional UNIX groups on the system."
echo "For local users using graphical desktop login managers such"
echo "as XDM/KDM, users may need to be members of additional groups"
echo "to access the full functionality of removable media devices."
echo
echo "* Security implications *"
echo "Please be aware that by adding users to additional groups may"
echo "potentially give access to the removable media of other users."
echo
echo "If you are creating a new user for remote shell access only,"
echo "users do not need to belong to any additional groups as standard,"
echo "so you may press ENTER at the next prompt."
echo
needinput=yes
while [ ! -z "$needinput" ]; do
history -c
history -s "$AGID"
echo "Press ENTER to continue without adding any additional groups"
echo "Or press the UP arrow to add/select/edit additional groups"
AGID="$(get_input ": " | tr -d '[:punct:]' | tr -s ' ' | sed 's?^ $??g' )"
if [ ! -z "$AGID" ]; then
check_group "$AGID" # check all groups at once (treated as N # of params)
if [ $? -gt 0 ]; then
echo "- Please re-enter the group(s)"
echo
else
unset needinput # we found all groups specified
AGID="-G $(echo $AGID | tr ' ' ,)" # useradd takes comma delimited groups
fi
else
unset needinput # we don't *have* to have additional groups
fi
done

#: Get the new user's home dir :#
#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
HME="$(get_input "Home directory [ ${defhome}/${LOGIN} ]")"
if [ -z "$HME" ]; then
HME="${defhome}/${LOGIN}"
fi
# Warn the user if the home dir already exists
if [ -d "$HME" ]; then
echo "- Warning: '$HME' already exists !"
getyn="$(get_input " Do you wish to change the home directory path ? (Y/n) ")"
if [ "$(echo $getyn | grep -i "n")" ]; then
unset needinput
# You're most likely going to only do this if you have the dir *mounted* for this user's $HOME
getyn="$(get_input " Do you want to chown $LOGIN.$( echo $GID | awk '{print $2}') $HME ? (y/N) ")"
if [ "$(echo $getyn | grep -i "y")" ]; then
CHOWNHOMEDIR=$HME # set this to the home directory
fi
fi
else
unset needinput
fi
done
HME="-d ${HME}"

#: Get the new user's shell :#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
unset got_error
SHL="$(get_input "Shell [ ${defshell} ]")"
if [ -z "$SHL" ]; then
SHL="${defshell}"
fi
# Warn the user if the shell doesn't exist in /etc/shells or as a file
if [ -z "$(grep "^${SHL}$" $sfile)" ]; then
echo "- Warning: ${SHL} is not in ${sfile} (potential problem using FTP)"
got_error=yes
fi
if [ ! -f "$SHL" ]; then
echo "- Warning: ${SHL} does not exist as a file"
got_error=yes
fi
if [ ! -z "$got_error" ]; then
getyn="$(get_input " Do you wish to change the shell ? (Y/n) ")"
if [ "$(echo $getyn | grep -i "n")" ]; then
unset needinput
fi
else
unset needinput
fi
done
SHL="-s ${SHL}"

#: Get the expiry date :#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
EXP="$(get_input "Expiry date (YYYY-MM-DD) []:")"
if [ ! -z "$EXP" ]; then
# Check to see whether the expiry date is in the valid format
if [ -z "$(echo "$EXP" | grep "^[[:digit:]]\{4\}[-]\?[[:digit:]]\{2\}[-]\?[[:digit:]]\{2\}$")" ]; then
echo "- That is not a valid expiration date"
else
unset needinput
EXP="-e ${EXP}"
fi
else
unset needinput
fi
done

# Display the info about the new impending account
echo
echo "New account will be created as follows:"
echo
echo "---------------------------------------"
display "Login name.......: " "$LOGIN"
display "UID..............: " "$_UID" "[ Next available ]"
display "Initial group....: " "$GID"
display "Additional groups: " "$AGID" "[ None ]"
display "Home directory...: " "$HME"
display "Shell............: " "$SHL"
display "Expiry date......: " "$EXP" "[ Never ]"
echo

echo "This is it... if you want to bail out, hit Control-C. Otherwise, press"
echo "ENTER to go ahead and make the account."
read junk

echo
echo "Creating new account..."
echo
echo

# Add the account to the system
CMD="$useradd "$HME" -m "$EXP" "$U_ID" "$GID" "$AGID" "$SHL" "$LOGIN""
$CMD

if [ $? -gt 0 ]; then
echo "- Error running useradd command -- account not created!"
echo "(cmd: $CMD)"
exit 1
fi

# chown the home dir ? We can only do this once the useradd has
# completed otherwise the user name doesn't exist.
if [ ! -z "${CHOWNHOMEDIR}" ]; then
chown "$LOGIN"."$( echo $GID | awk '{print $2}')" "${CHOWNHOMEDIR}"
fi

# Set the finger information
$chfn "$LOGIN"
if [ $? -gt 0 ]; then
echo "- Warning: an error occurred while setting finger information"
fi

# Set a password
$passwd "$LOGIN"
if [ $? -gt 0 ]; then
echo "* WARNING: An error occured while setting the password for"
echo " this account. Please manually investigate this *"
exit 1
fi

# If it was created (it should have been!), set the permissions for that user's dir
HME="$(echo "$HME" | awk '{print $2}')" # We have to remove the -g prefix
if [ -d "$HME" ]; then
$chmod $defchmod "$HME"
fi

echo
echo
echo "Account setup complete."
exit 0
Continue reading A script to add user in Linux