Open a Port on CentOS/RHEL

Along with numerous other changes, CentOS 7/RHEL 7 introduces firewalld:

Firewalld provides a dynamically managed firewall with support for network/firewall zones that define the trust level of network connections or interfaces. It has support for IPv4, IPv6 firewall settings, ethernet bridges and IP sets. There is a separation of runtime and permanent configuration options. It also provides an interface for services or applications to add firewall rules directly.

God knows learning iptables wasn't hard enough, here comes a big fat new layer to wrangle with the ostensible purpose of making things simpler while inherently adding a whole bunch of complexity and obscure inner workings. What could be more Red Hat? If your first inclination is to disable it and revert to pure iptables, power to you:
# systemctl stop firewalld # systemctl disable firewalld # systemctl mask --now firewalld # yum install iptables-services # systemctl start iptables # systemctl start iptables6 # systemctl enable iptables # systemctl enable iptables6
You are now free to use the conventional iptables configuration, i.e. issuing then dropping raw iptables commands to be run on boot into /etc/sysconfig/iptables
# iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT # iptables-save > /etc/sysconfig/iptables # service iptables restart

However if you choose to embrace the new paradigm it's simple enough to work with if you're willing to etch out some new space in your memory.

Open a port:
# firewall-cmd --permanent --add-port=80/tcp

Open a port range:
# firewall-cmd --permanent --add-port=80-81/tcp

After you have made the configuration change it is necessary to update the state of the firewall:
# firewall-cmd --reload

An interesting part of this new system for someone who is otherwise resentful may be the ability to open a service by name:
# firewall-cmd --permanent --add-service=http
In some cases this will execute additional operations, for example automatically loading relevant netfilter modules. Or, more interestingly, executing user-defined instructions...

Disable SELinux on CentOS/RHEL

SELinux: love it or hate it, it's a pain in the ass. Sometimes you just need it out of the way. I'm not here to judge.

Checking SELinux status:
# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 31

Disabling SELinux in real-time:
# setenforce 0

To prevent SELinux from being enabled on next boot edit /etc/selinux/config and set SELINUX to disabled:
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
If you have installed the setroubleshoot package you may notice setroubleshootd taking up CPU cycles; if you are permanently disabling selinux this daemon serves no function. It is launched by dbus rather than its own unit script; the easiest way to disable it is to simply remove the setroubleshoot package.
# yum remove setroubleshoot

arrowkeys.js: Bringing Life Back to the prev/next Link Tag with Keyboard Navigation

As you may know, Google no longer takes the ancient...
<link rel="prev" /> and <link rel="next" />
...tags into consideration; per https://searchengineland.com/google-no-longer-supports-relnext-prev-314319:

Google has stopped supporting the rel=next/prev markup it launched back in 2011. The interesting part is, Google has not supported it for the past few years and didn’t tell anyone!

Meanwhile, many indexers still do give credence to these tags and we can give them new purpose by combining them with an arrow key navigation technique already familiar to this blog:
function checkKeycode(e) { var keycode; if(window.event) keycode=window.event.keyCode; else if(e) keycode=e.which; var next = document.querySelector("link[rel*='next']").href; var prev = document.querySelector("link[rel*='prev']").href; if(navigator.appVersion.indexOf('MSIE') != -1) { if(keycode=='37' & typeof prev != 'undefined') window.location.href=prev; else if(keycode=='39' & typeof next != 'undefined') window.location.href=next; } else { if (e.target.tagName != 'INPUT' & e.target.tagName != 'TEXTAREA') { if(keycode=='37' & typeof prev != 'undefined') window.location.href=prev; else if(keycode=='39' & typeof next != 'undefined') window.location.href=next; } } } document.onkeyup=checkKeycode;
Example usage:
<head> <link rel="next" href="/arrowkeys-js" /> <link rel="prev" href="/hello-again-world" /> </head>
Values for the href attribute may be relative or fully qualified.

Enabling and Disabling Startup Services with systemd

I'm still getting used to the systemd paradigm on RHEL/CentOS 7 and instinctively reached for chkconfig to add xendomains to the runlevels:
chkconfig --level 2345 xendomains on
This works with older versions of Xen that come with SysV init scripts; later versions are shipping systemd init scripts and must be enabled the systemd way:
systemctl enable xendomains.service
To get a list of systemd scripts:
systemctl list-unit-files

Hello (Again) World: furry.media and How Karma got his Groove Back

Out with the old...
...in with the new.

I made my first furry site in 2002 as an exercise in developing my coding abilities. This quickly expanded into a portfolio of several sites which helped me cultivate skills that would come to greatly benefit me professionally. Unfortunately, maintaining and moderating online communities takes a substantial amount of time and the popularity of those communities demanded a level of hosting that at the time was very expensive. At one point the hosting bill was running in excess of $550CAD/month.

Although I accepted donations and ran ads on Ychan, donations were irregular and never covered more than a fraction of expenses. By 2014 the online advertising sector was at the bottom of a years-long decline and I was more busy than ever, having recently started my own company. When a direct-advertising partner for Ychan - our largest outside source of funding - pulled out of our arrangement I started thinking about winding down operations. As much as I wished the sites could have stayed online the enormous personal expense in keeping them funded precluded handing them over to someone else to manage. Additionally, the last major rewrite of the sites was in 2007 and by this time the codebase was an ageing patchwork that had potential security concerns for the users if a massive overhaul wasn't undertaken. After 11 continuous years of service I made the painful decision to shutter the sites so I could focus on my career and do the things necessary to ensure the security of my future: make investments, buy a house, cars etc.

About a year ago I found myself in California. I had accomplished everything I set out to do when I shut the sites down and, taken with the energy of Silicon Valley I suppose, started thinking about my next steps. Although I had been very fortunate professionally in the preceding years I had thoroughly burned myself out; typically putting in 12 hour days over 7 day weeks and sometimes working over 24 consecutive hours to meet critical deadlines. Almost all of this time was spent working to make other peoples' products and realize other peoples' dreams at the expense of my health and happiness. When you're doing all of your coding for the money and by the seat of your pants quality suffers, skills stagnate and frankly a part of your spirit dies. I missed the freedom that personal projects like my old furry sites afforded me to learn, grow and do the things that I wanted to do - without having to worry about budgets or deadlines or the silly whims and wishes of people who sign cheques.

Behold: kore

I came to the conclusion that the way I go about software development requires a sea change. I've learned a lot of neat tricks over the years that can only be properly implemented by starting a project from the beginning. At the same time I want to update my skill-set; I decided the best way to do that is to reignite the projects that gave me those skills in the first place. The cost of hosting is no longer an issue; it's now possible to do with one dedicated server what used to take us four. The problem of time remains, however: if I didn't have time to overhaul the furry sites in 2014 I certainly have less time now. If this was going to work I'd have to figure out a way to have my cake and eat it too.

To that end, I've set out to create a new software platform that will allow me to put all of my future efforts into a unified codebase that delivers every site and app from a single conceptual source. So much code from site to site and product to product is repeated with only minor variations that it is possible to reduce all of them to a set of core libraries plus a collection of simplified overlays. While I'm working on my furry sites which carry the freedom to do whatever I want, additions and improvements to the core codebase immediately become available to my professional projects and vice versa. Things like general maintenance and security enhancements can be done once without having to waste time repeating them at dozens of independent instances with varying conventions.

I started this blog in 2010 to organize coding and administration notes and so I would have a personal WordPress installation to maintain. This would force me to learn how to make templates, stay on top of security updates and general maintenance etc. for those clients that insisted on using it. Being common, complicated, off-the-shelf software, WordPress is naturally one of the most popular targets for exploitation and automated attacks. It wasn't long before I decided to stop supporting WordPress and the customers that use it altogether because the upkeep is simply not worth my time. I did find foxpa.ws itself to be worthwhile however and rewriting it with the new kore platform has given me the opportunity to create a powerful general-purpose content management system that can now be re-used in future kore-based projects while simultaneously giving me a platform to document and blog about its ongoing development.

The new foxpa.ws blog is written entirely from scratch, with the exception of the highlight.js library for code highlighting. The layout is - unlike its fixed-width predecessor - responsive and optimized for mobile viewing.


The plan now is to continue re-writing and re-launching the old sites with the kore platform under the new furry.media banner. Please stay tuned to this blog and the furry.media twitter feed if you would like to watch things take shape.