I use IRC….. a lot. I find it very useful as a help resource at any hour and unlike forums you’re more than likely to get an instant response. Whether the response is helpful or not however just comes down to what you’re asking, how helpful the people in the channel are and what mood people are in.

Some IRC channels are just nice to hang out in as you get to know people and can chat about common interests day or night.

As IRC generally uses some obscure ports they are blocked by most firewalls and I’ve run into this when using wifi on trains or at work etc… Also, if you’re connecting from various clients you’ll probably be connecting using multiple Nicks (annoying) and you won’t be logging the conversation while you were away.

IRC bouncers are the answer to this and the one I clearly have in mind is ZNC.

Personally I use Archlinux on all my machines (including servers) and have a home server that wasn’t doing very much so I thought I would put it go good use.

I followed the ArchWiki to install and set up znc as it does outline some best practices

I have a Virgin Media homehub at home and while I am planning on replacing this with a custom build and PFsense at some point (will probably merit a blog) I had to make do. Port forwarding is possible on the Homehub so i set it up to forward port 443 and (while I could have allowed znc to listen on this port requiring root) I chose to set up iptables to forward traffic from port 443 to the port znc is listening on.

(The server znc is running on will need a static IP address or a reservation otherwise when it changes the port forwarding will break.)

This was done with the following IPtables command (found here):

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumber

Where $srcPortNumber was 443 and $dstPortNumber was my ZNC listening port.

At this point all I had left to do was to set up dynamic dns so I didn’t have to constantly check my ip address as I do not have a static external address.

As I use namecheap for my domain I set up a new subdomain for ZNC and enabled dynamic dns on the domain. Namecpea then provided me with a password that I could use to configure a dynamic dns client.

I chose to use ddclient which at the time or writing is in the Archlinux Community repository.

I used the following configuration in /etc/ddclient/ddclient.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
daemon=600 # Checks every 600 seconds. More frequently can result in a ban from dyndns.org
syslog=yes
mail=root
mail-failure=root
pid=/var/run/ddclient.pid
ssl=yes

use=web, web=checkip.dyndns.org/, web-skip='IP Address' # Server to check for our IP

protocol=namecheap
server=dynamicdns.park-your-domain.com 
login= # Put your domain name here
password= # The dynamic dns password provided to you by namecheap
hostname # The hostname you want to provide the IP address for. Only the hostname is needed, NOT the full domain name.

This information was mainly poached from namecheap

When I first configured ZNC I had problems configuring dynamic dns for a namecheap subdomain. To get around this problem I wrote a quick script that would check my IP address and email me every time it changed with the new IP. The frequency of the check was determined by how often cron called the script.

You will need to set up mail on the server. Personnally I used ssmtp I may blog on this later as not to derail this port further.

dyndns.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env ruby
require 'rubygems'
require 'open-uri'
require 'nokogiri'
require 'fileutils'
require 'logger'

mail = "myemail@provider.com"
ipfile = "/var/lib/znc/.dyndns/dyndnsip"
log = Logger.new('/var/lib/znc/.dyndns/log.txt')
log.level = Logger::INFO

log.info "##### STARTING #####"

log.info "Contacting DYNDNS"

begin
	HTML = open("http://checkip.dyndns.com", &:read)
	newip = Nokogiri::HTML(HTML).text.split(" ").last
	log.info "Dyndns reports: " + newip
rescue Exception=>e
	log.fatal "Failed to get IP from dyndns, logging and exiting: " + e
	exit(1)
end

begin
	unless File.exist?(ipfile)
		log.warn "Last IP file missing, creating..."
		FileUtils.touch ipfile
	end

	unless File.zero?(ipfile)
		lastip = File.open(ipfile, &:readline)
		log.info "File reports: " + lastip
	else
		log.warn "Last IP file empty, please ignore if just created"
		lastip = "none"
	end
rescue Exception=>e
	log.fatal "Fatal Error encountered with file handling, exiting..."
	exit(1)
end

unless lastip == newip
	log.info "IP Address has changed"
	log.info "Saving: " + newip + " to file."
	File.open(ipfile, 'w') {|f| f.write(newip) }
	log.info "Sending Email with: " + newip
	
	status = "ZNC Status: " + "\n" +	%x[systemctl show znc | grep State]
	message = "ZNC IP Address is now: " + newip
	output = message + "\n" + status
	if system(" echo '#{output}' | mail -s 'ZNC IP Address Update' #{mail} ")
		log.info "Email sent!"
	else
		log.warn "Email Failed"
	end

else
	log.info "IP Address has not changed"
end

log.info "##### EXITING #####"

I know the script is fairly poor but it worked until I had time to figure out ddclient and namecheap. (I didn’t get round to it for several months) I simply ran it with cron. As it runs inside an rvm environment and cron does not load the user’s environment I used the following in crontab:

(Edit to fit your own environment)

1
*/15 * * * * /bin/bash -l -c 'source "$HOME/.rvm/scripts/rvm" && rvm use 2.1.0@znc && cd $HOME && ruby dyndns.rb'

I’m hoping that more of my future blog posts will be as detailed as this one. If I missed anything out please don’t hesitate to contact me.