{"id":27,"date":"2008-11-09T18:52:15","date_gmt":"2008-11-10T01:52:15","guid":{"rendered":"http:\/\/www.1oc.com\/blog\/?p=27"},"modified":"2008-11-09T18:52:15","modified_gmt":"2008-11-10T01:52:15","slug":"securing-trixbox-ce","status":"publish","type":"post","link":"http:\/\/blog.1oc.com\/?p=27","title":{"rendered":"Securing Trixbox"},"content":{"rendered":"<p>Based on Tim Yardley&#8217;s document<\/p>\n<p>\u00a0<\/p>\n<h2>Services<\/h2>\n<p>The first steps I normally take to secure any server that is my responsibility is to\u00a0ensure all services that are not needed are disabled. This can be done with the <em>chkconfig<\/em><\/p>\n<p>command. To list what services are starting at boot issue the following command. I\u00a0have highlighted the services that are started on boot.<\/p>\n<p><strong><em>[trixbox1.localdomain ~]# chkconfig &#8211;list<\/em><\/strong><\/p>\n<p><a href=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-67\" title=\"picture-11\" src=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-11-231x300.png\" alt=\"\" width=\"231\" height=\"300\" srcset=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-11-231x300.png 231w, http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-11.png 579w\" sizes=\"auto, (max-width: 231px) 100vw, 231px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-68\" title=\"picture-2\" src=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-2-300x111.png\" alt=\"\" width=\"300\" height=\"111\" srcset=\"http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-2-300x111.png 300w, http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-2-500x186.png 500w, http:\/\/blog.1oc.com\/wp-content\/uploads\/2008\/12\/picture-2.png 574w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>xinetd based services:<\/p>\n<pre style=\"padding-left: 30px; \">chargen-dgram: off<\/pre>\n<pre style=\"padding-left: 30px; \">chargen-stream: off<\/pre>\n<pre style=\"padding-left: 30px; \">daytime-dgram: off<\/pre>\n<pre style=\"padding-left: 30px; \">daytime-stream: off<\/pre>\n<pre style=\"padding-left: 30px; \">discard-dgram: off<\/pre>\n<pre style=\"padding-left: 30px; \">discard-stream: off<\/pre>\n<pre style=\"padding-left: 30px; \">echo-dgram: off<\/pre>\n<pre style=\"padding-left: 30px; \">echo-stream: off<\/pre>\n<pre style=\"padding-left: 30px; \">rsync: off<\/pre>\n<pre style=\"padding-left: 30px; \">tcpmux-server: off<\/pre>\n<pre style=\"padding-left: 30px; \">tftp: on<\/pre>\n<pre style=\"padding-left: 30px; \">time-dgram: off<\/pre>\n<pre style=\"padding-left: 30px; \">time-stream: off<\/pre>\n<p>Now we can see that several services have started that we may or may not want\u00a0on. Anacron, crond, haldaemon, httpd, kudzu, lm_sensors, lvm2-monitor,\u00a0mDNSResponder, mdmonitor, memcached, messagebus, mysqld, network, ntpd, postfix,\u00a0sshd, syslog, xinetd, and zaptel are all required to be on for a functioning trixbox system.<\/p>\n<p>The rest of the services can be disabled. If you plan to use ftp on the system, then leave\u00a0vsftpd on. You can use <em>chkconfig &lt;service name&gt; off<\/em>.<\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig ircd off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig netfs off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig nfslock off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig openibd off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig portmap off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig restorecond off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig rpcgssd off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig rpcidmapd off<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>chkconfig vsftpd off<\/em><\/p>\n<p>Now that we have the services disabled from starting at boot, lets go ahead and\u00a0stop them from running right now.<\/p>\n<p style=\"padding-left: 30px; \"><em>service ircd stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service netfs stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service nfslock stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service openibd stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service portmap stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service restorecond stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service rpcgssd stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service rpcidmapd stop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>service vsftpd stop<\/em><\/p>\n<h2>Securing SSH<\/h2>\n<p>Securing sshd is critical to ensuring a somewhat worry free system. There are\u00a0several ways to make it more difficult to get into a server over ssh.<\/p>\n<p>Step 1. Create a user on the system to only allow ssh connections from. The\u00a0username should be something that you only know and is not easily guessed. Here we\u00a0will create a user called <em>trixuser <\/em>and assign a password to it. The password should be\u00a0something with letters, numbers, symbols and not based off a dictionary word. For good\u00a0passwords, try to use something that is both obscene and vulgar, this ensures that you\u00a0will never repeat it out loud or want to tell anyone what it is. Also try and string it into a\u00a0sentence making sure to use the letters, numbers, and symbols. Spaces in passwords\u00a0work good too and are hard to add in scripts that might try to break into your server.<\/p>\n<p><strong><em>[trixbox1.localdomain init.d]# useradd trixuser<\/em><\/strong><\/p>\n<p><strong><em>[trixbox1.localdomain init.d]# passwd trixuser<\/em><\/strong><\/p>\n<p>Now ensure that the new account works by using ssh to login to the trixbox CE\u00a0server with this new account. If it does not let you in, make sure the password is correct\u00a0or try to reset it. If it works continue on.<\/p>\n<p>Only allowing one account access to the system over ssh is a great way to lock out\u00a0most brute force attacks. To do this we need to edit the file in \/etc\/ssh\/sshd_config and\u00a0add the following to the file.<\/p>\n<p><strong><em>AllowUsers trixuser<\/em><\/strong><\/p>\n<p>I like to edit the <em>PermitRootLogin <\/em>setting so that root can&#8217;t login over ssh.<\/p>\n<p>Remove the # from in front of the setting and change the yes to no.<\/p>\n<p><strong><em>PermitRootLogin no<\/em><\/strong><\/p>\n<p>Finally, I would recommend changing the Port setting from the standard 22, which\u00a0everyone knows as ssh, to something else. Be careful what you change it to, you don&#8217;t\u00a0want the port to conflict with a port in use or that might become in use. You can also\u00a0attract more attention to the server if you put it on another known port than if you left it\u00a0at 22. In this example we will use 2222. Please decide on your own port number to use\u00a0on your system. The setting we edit is <em>Port 22 <\/em>in \/etc\/ssh\/sshd_config. Remove the #\u00a0from in front of the setting and change 22 to 2222.<\/p>\n<p>Port 2222<\/p>\n<p>We need to restart sshd for the changes to take affect. Please use caution when\u00a0changing these settings on a remote system that you can&#8217;t easily get too. If there is a\u00a0error in the config it could cause sshd to not restart.<\/p>\n<p>service sshd restart<\/p>\n<p>Now test to make sure that you can get into the server over ssh. The root user\u00a0should be denied access and only the user we created should be allowed to get in. Don&#8217;t\u00a0forget to change your ssh port to 2222 when connecting. In putty it is listed next to the\u00a0IP address, on the command line the flag is <em>-p port<\/em>.<\/p>\n<h2>Firewall APF and BFD<\/h2>\n<p>I like to use rfxnetworks apf and bfd for fire walling all my systems. Links to<\/p>\n<p>their software can be found here.<\/p>\n<p><span><strong>apf<\/strong> &#8211; <\/span><a href=\"http:\/\/rfxnetworks.com\/apf.php\" target=\"_blank\">http:\/\/rfxnetworks.com\/apf.php<\/a><\/p>\n<p><span><strong>bfd<\/strong> &#8211; <\/span><a href=\"http:\/\/rfxnetworks.com\/bfd.php\">http:\/\/rfxnetworks.com\/bfd.php<\/a><\/p>\n<p>rfxnetworks has many other great projects that are worth looking at. But this document\u00a0will only cover apf\/bfd.<\/p>\n<p>APF stands for Advanced Policy Firewall. This is used to control iptables on the\u00a0system to allow or disallow ports to be open. APF has additional features that make it\u00a0stand out above the rest. Reactive address blocking (RAB), QoS (TOS), direct<\/p>\n<p>integration with BFD, many many more, see site for full details.<\/p>\n<p>BFD stands for Brute Force Detection. This is used to monitor any failed logins\u00a0and block IP addresses from getting in. This runs as a cron daemon and works perfectly\u00a0with APF.<\/p>\n<p>To install both of these applications is very simple. You can download them both\u00a0from the rfxnetworks links, uncompress them, and then run the install.sh script. I have\u00a0also created a installer script that can be downloaded to your machine and ran. This will\u00a0install the latest and greatest apf\/bfd. To get this script you will need to use wget or\u00a0other method to pull it off a web server. You will also want to do this as root.<\/p>\n<p><span><strong><em>wget <\/em><\/strong><\/span><strong><em>http:\/\/engineertim.com\/install_apf_bfd.sh<\/em><\/strong><\/p>\n<p><strong><em>chmod 755 install_apf_bfd.sh<\/em><\/strong><\/p>\n<p><strong><em>.\/install_apf_bfd.sh<\/em><\/strong><\/p>\n<p>This will start the install process for both apf and bfd. Once completed you will\u00a0be returned to a command prompt.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">APF<\/span><\/strong><\/p>\n<p>To configure APF is pretty easy and I will touch on a few of the config file options\u00a0in this document. All of the options are covered in great detail on their website and well\u00a0commented in the conf.apf file.<\/p>\n<p>The config file for APF lives in \/etc\/apf and is called conf.apf<\/p>\n<p>We will need to edit the conf.apf file, I like to use vi but any command line editor\u00a0will work.<\/p>\n<p>If you have multiple interfaces on your trixbox setup, you will want to set the\u00a0IFACE_IN and IFACE_OUT to your external interface. This is the, untrusted network\u00a0interface that is connected to the internet. If you have a second card eth1, that is used<\/p>\n<p>for internal network, trusted network, you can set the IFACE_TRUSTED to this\u00a0interface. Please see the comments in the conf.apf if you are uncertain.<\/p>\n<p>The setup script will try to properly determine which interface is used for\u00a0untrusted network and place it in the appropriate field.<\/p>\n<p>I like to change the value of the SET_TRIM to 0. This value sets the total amount\u00a0of rules allowed inside of the deny trust system. It is designed to save memory and start\u00a0time. With the default value of 50, the system will start to purge old rules once this<\/p>\n<p>number is met. With the inclusion of BFD, this number will generally climb past 50.<\/p>\n<p>Setting this value to 0 will disable this feature.<\/p>\n<p><strong><em>SET_TRIM=\u201d0\u201d<\/em><\/strong><\/p>\n<p>APF has the ability to do QoS on packets, this is defined with the TOS values in\u00a0the conf.apf. For SIP and IAX, I set the following.<\/p>\n<p><strong><em>TOS_8=&#8221;21,20,80,4569,5060,10000_20000&#8243;<\/em><\/strong><\/p>\n<p>This also requires a small tweak to one of the config files that I will discuss later\u00a0in the document in order to tag UDP packets.<\/p>\n<p>Since we changed the SSH port to a different number, we have to tweak the\u00a0conf.apf to match this new port.<\/p>\n<p><strong><em>HELPER_SSH_PORT=&#8221;2222&#8243;<\/em><\/strong><\/p>\n<p>Make sure to place the correct port number that you decided to run SSH on.<\/p>\n<p>Ingress filtering is used to open inbound ports for access, both TCP and UDP have\u00a0separate settings. For a trixbox setup, the following ports should be open, both TCP and\u00a0UDP are listed. If you are not using tftp, then do not have port 69 open. Do not forget to\u00a0change the SSH port from 22, to the port you choose to run SSH on. Otherwise you will\u00a0be locked out, here we are using port 2222 from our example above. I have not included\u00a0IAX ports in this setup. There is a easy way to ensure that only specific hosts can use\u00a0IAX that I will cover later. This is handy if you use IAX to do interoffice trunks like I\u00a0do, but don&#8217;t want IAX ports open for the world to see.<\/p>\n<p><strong><em>IG_TCP_CPORTS=&#8221;2222,69,80,5060,6600,10000_20000&#8243;<\/em><\/strong><\/p>\n<p><strong><em>IG_UDP_CPORTS=&#8221;69,5060,10000_20000&#8243;<\/em><\/strong><\/p>\n<p>Egress filtering is used to allow outbound filtering. I don&#8217;t use egress filtering and\u00a0it will not be covered in this document. It is set to EGF=\u201d0\u201d , or disabled by default.<\/p>\n<p>In the section of the conf.apf file called Imported Rules, there are settings for\u00a0various feeds. Some of these feeds are very handy and I use them all. I have even setup\u00a0my own custom feed that allows me to tweak all of my servers with global deny rules.<\/p>\n<p>You can disable or enable this feature with the USE_DS setting. A \u201c1\u201d is enabled, a \u201c0\u201d\u00a0is disabled.<\/p>\n<p>We are now ready to start APF for the first time. Double check that the SSH port\u00a0is set correctly to the one you are using. If you start APF right now and something is\u00a0wrong, it will disable itself in 5 minutes. This is called DEVEL_MODE and is the first<\/p>\n<p>setting in the conf.apf file. Leave this set to \u201c1\u201d until you are certain you can get in via\u00a0ssh and things are working.<\/p>\n<p>To see a list of command line options run <em>apf <\/em>without any flags.<\/p>\n<p><strong><em>[trixbox1.localdomain apf]# apf<\/em><\/strong><\/p>\n<p style=\"padding-left: 30px; \">a<em>pf(3402): {glob} status log not found, created<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>APF version 9.6 &lt;apf@r-fx.org&gt;<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>Copyright (C) 1999-2007, R-fx Networks &lt;proj@r-fx.org&gt;<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>Copyright (C) 2007, Ryan MacDonald &lt;ryan@r-fx.org&gt;<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>This program may be freely redistributed under the terms of the GNU GPL<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>usage \/usr\/local\/sbin\/apf [OPTION]<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-s|&#8211;start &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;. load all firewall rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-r|&#8211;restart &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.. stop (flush) &amp; reload firewall rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-f|&#8211;stop&#8230;&#8230;.. &#8230;&#8230;&#8230;&#8230;&#8230;&#8230; stop (flush) all firewall rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-l|&#8211;list &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.. list all firewall rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-t|&#8211;status &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230; output firewall status log<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-e|&#8211;refresh &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.. refresh &amp; resolve dns names in trust rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-a HOST CMT|&#8211;allow HOST COMMENT &#8230; add host (IP\/FQDN) to allow_hosts.rules and<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>immediately load new rule into firewall<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-d HOST CMT|&#8211;deny HOST COMMENT &#8230;. add host (IP\/FQDN) to deny_hosts.rules and<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>immediately load new rule into firewall<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-u|&#8211;remove HOST &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;. remove host from [glob]*_hosts.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>and immediately remove rule from firewall<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>-o|&#8211;ovars &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;. output all configuration options<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>To start APF we issue the following command.<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>[trixbox1.localdomain apf]# apf -s<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3445): {glob} activating firewall<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} determined (IFACE_IN) eth0 has address 192.168.1.31<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} determined (IFACE_OUT) eth0 has address 192.168.1.31<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} loading preroute.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {resnet} downloading http:\/\/r-fx.ca\/downloads\/reserved.networks<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {resnet} parsing reserved.networks into<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>\/etc\/apf\/internals\/reserved.networks<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} loading reserved.networks<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} SET_REFRESH is set to 10 minutes<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} loading bt.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {dshield} downloading http:\/\/feeds.dshield.org\/top10-2.txt<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {dshield} parsing top10-2.txt into \/etc\/apf\/ds_hosts.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {dshield} loading ds_hosts.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {sdrop} downloading http:\/\/www.spamhaus.org\/drop\/drop.lasso<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {sdrop} parsing drop.lasso into \/etc\/apf\/sdrop_hosts.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {sdrop} loading sdrop_hosts.rules<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} loading common drop ports<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>&#8230;&#8230;&#8230;..trimmed for this document&#8230;&#8230;&#8230;<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3489): {glob} default (ingress) input drop<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3445): {glob} firewall initalized<\/em><\/p>\n<p style=\"padding-left: 30px; \"><em>apf(3445): {glob} !!DEVELOPMENT MODE ENABLED!! &#8211; firewall will flush every 5\u00a0minutes.<\/em><\/p>\n<p>We can see that APF has started, downloaded some rules from dshield.org and\u00a0spamhaus.org and then told us it is in DEVELOPMENT MODE. Now test connecting\u00a0to your server over SSH to ensure that you have setup the correct port number ingress.<\/p>\n<p>If you can&#8217;t connect, you will have to wait 5 minutes and then APF will shutdown. Once\u00a0you are sure you can get in with SSH we can change the conf.apf file from\u00a0DEVEL_MODE=&#8221;1&#8243; to DEVEL_MODE=&#8221;0&#8243; and restart\/start APF. APF will start and\u00a0not warn you about being in DEVELOPMENT MODE, your firewall should be good to\u00a0go.<\/p>\n<p>APF additional tweaks. This setup might not be ideal for everyone. If you\u00a0connect to your provider over IAX then you will definitely want to add the IAX ports to\u00a0the conf.apf. However if you have two or more systems that you connect to each other\u00a0over IAX for interoffice connections, then this is the way to go. This will work with\u00a0static IP addresses and DYNDNS setups alike. You can use a fully qualified DNS\u00a0hostname or IP address. One of the flags for the apf command is -a, which is allow.<\/p>\n<p>This will globally allow a host to connect to this system, bypassing the firewall rules. I\u00a0can&#8217;t stress how handy this is. Some examples are allowing a SNMP query, IAX\u00a0connections, or other ports that you do not want open, but need to allow specific hosts to<\/p>\n<p>connect to. To do this just issue the following command, substitute your remote system\u00a0IP address with the one I have here.<\/p>\n<p><em><strong>apf -a 192.168.1.216<\/strong><\/em><\/p>\n<p>This will allow the system 192.168.1.216 to connect to any port on the firewalled\u00a0server, thereby bypassing the firewall rules. If you are running APF on both systems, be\u00a0sure to do the same thing on the other host using the correct IP address.<\/p>\n<p>APF also allows a system admin to block a host or a complete subnet. This is\u00a0handy if you see someone attempting to connect to your machine over ftp, telnet, ssh,\u00a0etc.. To block a specific host use the following, be sure to use the IP you want to block.<\/p>\n<p><em><strong>apf -d 192.168.1.216<\/strong><\/em><\/p>\n<p>To block a complete subnet (CIDR) the command is very similar.<\/p>\n<p><em><strong>apf -d 202.86.128.0\/24<\/strong><\/em><\/p>\n<p>This will block the entire subnet. You can sometimes get the subnet (CIDR)\u00a0listing using a whois on the IP address. You can also lookup a CIDR by ip on google or\u00a0ripe.net. Be sure that the subnet is not one you are in or you could lock yourself out.<\/p>\n<p>TOS for UDP packets are not defined for APF. Only TCP packets have the TOS\u00a0bit set. There is a easy way to fix this. In the \/etc\/apf\/internals folder is a file called,\u00a0functions.apf. We need to edit this file manually. It is pretty straight forward as to what\u00a0we need to changed, so don&#8217;t worry.<\/p>\n<p>There are several places we have to add a single line. Look for the TOS_ section\u00a0in the functions.apf. It will look like this.<\/p>\n<p style=\"padding-left: 30px; \"><em><strong>if [ ! &#8220;$TOS_0&#8221; == &#8220;&#8221; ]; then<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>for i in `echo $TOS_0 | tr &#8216;,&#8217; &#8216; &#8216;`; do<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>i=`echo $i | tr &#8216;_&#8217; &#8216;:&#8217;`<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>$IPT -t mangle -A PREROUTING -p tcp &#8211;sport $i -j TOS &#8211;set-tos 0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>done<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>fi<\/strong><\/em><\/p>\n<p>We have to add the settings for UDP. We copy one line and change tcp to upd. A\u00a0sample is below, highlighted in red.<\/p>\n<p style=\"padding-left: 30px; \"><em><strong>if [ ! &#8220;$TOS_0&#8221; == &#8220;&#8221; ]; then<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>for i in `echo $TOS_0 | tr &#8216;,&#8217; &#8216; &#8216;`; do<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>i=`echo $i | tr &#8216;_&#8217; &#8216;:&#8217;`<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>$IPT -t mangle -A PREROUTING -p tcp &#8211;sport $i -j TOS &#8211;set-tos 0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>$IPT -t mangle -A PREROUTING -p udp &#8211;sport $i -j TOS &#8211;set-tos 0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>done<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px; \"><em><strong>fi<\/strong><\/em><\/p>\n<p>This additional line has to be done for all the TOS bits you are using. If you are\u00a0only using TOS_8 , then only worry about doing it for those. Make sure you do the\u00a0tospostroute and tospreroute sections.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">BFD<\/span><\/strong><\/p>\n<p>Brute force detection is used to capture illegitimate login attempts for services on\u00a0the system. I see quite often a large number of ssh attempts into several servers that\u00a0have not had the ssh port changed. These attempts are often a outside attempt to gain<\/p>\n<p>access by running dictionary attacks against common user names. These can now easily\u00a0be stopped by using BFD. If you ran the install_apf_bfd.sh then bfd should be installed.<\/p>\n<p>The configuration file for bfd is located in \/usr\/local\/bfd and is called conf.bfd.<\/p>\n<p>This file, like the one for apf, is heavely commented and covered in great detail on the\u00a0rfxnetworks website. I will just be covering some of the settings.<\/p>\n<p>I should first premise this by stating that you can become locked out of your own\u00a0server if you fail to type your own password correctly. This is another good reason to\u00a0add a trusted system using the <em>apf -a <\/em>command. You can also add a host to ignore by<\/p>\n<p>adding the IP address to the \/usr\/local\/bfd\/ignore.hosts file. The ban command that BFD\u00a0uses is tied directly to APF. The command is <em>apf -d<\/em>, which is the same way I showed\u00a0you to manually ban addresses and subnets.<\/p>\n<p>The first configuration variable we will look at is TRIG, this is the number of\u00a0failed attempts before becoming banned. The default is 15 and is pretty good. Keep in\u00a0mind this is per IP address connections, not account. So if 1 IP address fails 15 times\u00a0using multiple accounts, it will be banned. Feel free to change this value if you want,\u00a0don&#8217;t make it to high of a number as this will allow more attempts to be made.<\/p>\n<p>BFD has the ability to send emails out to alert of brute force attempts. This is a\u00a0good idea, but it also requires that your trixbox setup can properly send emails. I will\u00a0not be covering how to setup the server for mail in this document. To enable email\u00a0alerts set the value of EMAIL_ALERTS to 1, then set the address you want emails to be\u00a0sent to using EMAIL_ADRESS. You can define the subject for the email as well. This\u00a0makes for easy flagging\/filtering in email applications.<\/p>\n<p>BFD runs from cron and places a cron entry in \/etc\/cron.d called bfd. This runs\u00a0bfd every 3 minutes. This should be acceptable for almost anyone.<\/p>\n<p>You can get a list of offending IP addresses using BFD on the command line. This\u00a0is useful for looking at specific IP subnets that you might want to start blocking, if you\u00a0see a pattern starting. To get this list the following command is used.<\/p>\n<p><em><strong>bfd \u2013 a<\/strong><\/em><\/p>\n<p><strong><span style=\"text-decoration: underline;\">Securing HTTP<\/span><\/strong><\/p>\n<p>I like to secure my entire http access on trixbox to only allow a select few users to\u00a0gain access. So when a person goes to http:\/\/ip_address ; they are prompted right away\u00a0for a login. This can be a global login, or a per user account login. This login can also\u00a0only allow \/user\/ access while a administrator account can be setup to allow access to\u00a0the entire system. This setup is easy to enable and provides very fine grained access\u00a0control. It will also keep unwanted people (hackers) from gaining access to the web\u00a0interface.<\/p>\n<p>I like to use mod_auth_mysql to lock down http. You can use plain mod_auth if\u00a0you don&#8217;t want to install new software. I will cover configuring both setups.<\/p>\n<p><span style=\"color: #888888;\">mod_auth_mysql<\/span> can be used to limit access to documents served by apache by\u00a0checking data in a MySQL database. All of my accounts are stored in MySQL along\u00a0with groups, passwords, etc. To install mod_auth_mysql we will use yum, this will\u00a0resolve any dependencies that might pop up.<\/p>\n<p><strong><em>yum install mod_auth_mysql<\/em><\/strong><\/p>\n<p>When it asks \u201cIs this ok [y\/N]:\u201d just put \u201cy\u201d and hit enter. This will install the\u00a0module in the appropriate location.<\/p>\n<p>We now need to edit the configuration file. The configuration is located in\u00a0\/etc\/httpd\/conf.d and it is called auth_mysql.conf. Edit this file with your favorite editor\u00a0with the following, or something similar.<\/p>\n<p style=\"padding-left: 60px; \"><em>LoadModule mysql_auth_module modules\/mod_auth_mysql.so<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&lt;Directory \/var\/www\/html&gt;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthName &#8220;Authentication Required&#8221;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthType Basic<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMYSQLEnable on<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLUser root<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLPassword passw0rd<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLDB userauth<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLUserTable users<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLNameField user_name<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLPasswordField user_passwd<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLGroupTable groups<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLGroupField user_group<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>require group user<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>require valid-user<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&lt;\/Directory&gt;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&lt;Directory \/var\/www\/html\/maint&gt;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthName &#8220;Authentication Required&#8221;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthType Basic<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMYSQLEnable on<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLUser root<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLPassword passw0rd<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLDB userauth<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLUserTable users<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLNameField user_name<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLPasswordField user_passwd<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLGroupTable groups<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>AuthMySQLGroupField user_group<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>require group admin<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&lt;\/Directory&gt;<\/em><\/p>\n<p>If you have changed your root mysql password from the default, you will have to\u00a0update the configuration above to reflect this new password. You can also change the\u00a0groups if you feel you need to. I use admin and user, to reflect the level of access.<\/p>\n<p>We now need to create a new database, I call mine userauth. To do this I use\u00a0mysqladmin, you can use phpmyadmin if you would like.<\/p>\n<p><strong><em>mysqladmin -uroot -p create userauth<\/em><\/strong><\/p>\n<p>We now need to populate our database with our tables. Below is a schema that is\u00a0used to do just that. Copy the following to a new file on the system and call it\u00a0userauth.schema.sql , watch for formatting when copying this. You can alternatively use\u00a0phpmyadmin to create the tables.<\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; MySQL dump 10.10<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; Host: localhost Database: userauth<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; Server version5.0.22<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET NAMES utf8 *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40103 SET TIME_ZONE=&#8217;+00:00&#8242; *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=&#8217;NO_AUTO_VALUE_ON_ZERO&#8217; *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; Current Database: `userauth`<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>CREATE DATABASE \/*!32312 IF NOT EXISTS*\/ `userauth` \/*!40100 DEFAULT CHARACTER SET<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>latin1 *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>USE `userauth`;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; Table structure for table `groups`<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>DROP TABLE IF EXISTS `groups`;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>CREATE TABLE `groups` (<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`user_name` char(30) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`user_group` char(20) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>PRIMARY KEY (`user_name`,`user_group`)<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>) ENGINE=MyISAM DEFAULT CHARSET=latin1;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212; Table structure for table `users`<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>&#8212;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>DROP TABLE IF EXISTS `users`;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>CREATE TABLE `users` (<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`user_name` char(30) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`user_passwd` char(20) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`extension` int(10) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>`email` char(50) NOT NULL,<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>PRIMARY KEY (`user_name`)<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>) ENGINE=MyISAM DEFAULT CHARSET=latin1;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET SQL_MODE=@OLD_SQL_MODE *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION *\/;<\/em><\/p>\n<p style=\"padding-left: 60px; \"><em>\/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES *\/;<\/em><\/p>\n<p>We now need to import the schema into the database. We do this with the mysql\u00a0command.<\/p>\n<p><em><strong>mysql -uroot -p userauth &lt; userauth.schema.sql<\/strong><\/em><\/p>\n<p>This will import the sql schema into mysql for use. We now need to populate our\u00a0database with the users. This can be done with phpmyadmin easily, I will show you how\u00a0to do it using mysql.<\/p>\n<p>mysql -uroot -p<\/p>\n<p>mysql&gt; use userauth;<\/p>\n<p>INSERT INTO `userauth`.`users` (`user_name` ,`user_passwd` ,`extension` ,`email`)<\/p>\n<p>VALUES (&#8216;engineertim&#8217;, ENCRYPT(&#8216;letmein&#8217;),&#8221;,&#8221; );<\/p>\n<p>INSERT INTO `userauth`.`users` (`user_name` ,`user_passwd` ,`extension` ,`email`)<\/p>\n<p>VALUES (&#8216;kerry&#8217;, ENCRYPT(&#8216;letmein&#8217;),&#8221;,&#8221; );<\/p>\n<p>INSERT INTO `groups` VALUES (&#8216;engineertim&#8217;,&#8217;user&#8217;),(&#8216;engineertim&#8217;,&#8217;admin&#8217;),<\/p>\n<p>(&#8216;kerry&#8217;,&#8217;user&#8217;)<\/p>\n<p>mysql&gt; exit<\/p>\n<p>The first INSERT INTO, adds the user engineertim with a encrypted password of\u00a0letmein. The second INSERT INTO, adds another user kerry with a encrypted password\u00a0of letmein. The final INSERT INTO, puts the created users in their groups for\u00a0permissions. The engineertim user is added to the user and admin group, while the kerry\u00a0user is added to the user group. Feel free to change the names and passwords to\u00a0whatever you want. If you copy and paste this, watch the formatting. Those are all\u00a0suppose to be one long line of text for each INSERT INTO.<\/p>\n<p>We now need to edit the \/etc\/httpd\/conf\/httpd.conf file. You will want to comment\u00a0out the last line. It should look like this.<\/p>\n<p><strong>#Include \/etc\/trixbox\/httpdconf\/*<\/strong><\/p>\n<p>Now it is time to restart httpd and test our results. Don&#8217;t worry if it does not work\u00a0the only change you need to make to revert back is to remove the comment line from\u00a0\/etc\/httpd\/conf\/httpd.conf and move the \/etc\/httpd\/conf.d\/auth_mysql.conf file\u00a0somewhere\u00a0and restart httpd. To restart httpd issue the following command.<\/p>\n<p><strong><em>service httpd restart<\/em><\/strong><\/p>\n<p>Now goto your trixbox server from a web browser. Right away you should be\u00a0presented with a login window, you can provide the credentials to any of the users you\u00a0created and get in. Depending on whether that login is part of the admin group will\u00a0determine if they can get into the maint section of the trixbox web page. If the login is\u00a0in both groups, then that login can view both.<\/p>\n<p>This setup will prevent a lot of unwanted scraping and hacking on the system and\u00a0just generally protect the user interface from traffic. If your trixbox is forward facing on\u00a0the internet, then locking down the user portal is, in my opinion, critical to the proper\u00a0function of the system.<\/p>\n<p>You might have noticed that in the database schema I included two tables that\u00a0were not used. These are email and extension. These tables will be used in a upcoming\u00a0document. If you do not want to use them, feel free to exclude them. However, I will be\u00a0showing you how to integrate postfix and mysql at a later date that will tie it all together.<\/p>\n<p>It is also handy to put in the extension and email of the account created for tracking.<\/p>\n<p>A little easier approach.<\/p>\n<p>If you do not want to use mod_auth_mysql and want to stick with the current\u00a0htpasswd setup then I will show you a few tweaks to lock down the user panel. The file\u00a0in \/etc\/trixbox\/httpdconf\/trixbox.conf has a few settings for \/admin\/ and \/maint\/. We\u00a0want to edit this file to include \/user\/. Open the file in your favorite linux editor and add\u00a0the following.<\/p>\n<p style=\"padding-left: 60px; \"><em><strong>#Password protect \/var\/www\/html<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>&lt;Directory \/var\/www\/html&gt;<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>AuthType Basic<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>AuthName &#8220;Restricted Area&#8221;<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>AuthUserFile \/usr\/local\/apache\/passwd\/wwwpasswd<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>Require user maint engineertim<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px; \"><em><strong>&lt;\/Directory&gt;<\/strong><\/em><\/p>\n<p>We now need to add the user engineertim to the AuthUserFile. Issue the\u00a0following command on the command line.<\/p>\n<p><em><strong>htpasswd \/usr\/local\/apache\/passwd\/wwwpasswd engineertim<\/strong><\/em><\/p>\n<p>It will ask for a password for this user and then confirm it by typing it again. You\u00a0will now need to restart httpd for this change to take affect.<\/p>\n<p><em><strong>service httpd restart<\/strong><\/em><\/p>\n<p>Now try out your trixbox login. Be sure to close any existing browsers that is\u00a0logged into the trixbox server. It might be required to clear cookies and cache as well.<\/p>\n<p>\u00a0<\/p>\n<p>Thank you for taking the time to read this.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Based on Tim Yardley&#8217;s document \u00a0 Services The first steps I normally take to secure any server that is my responsibility is to\u00a0ensure all services that are not needed are disabled. This can be done with the chkconfig command. To &hellip; <a href=\"http:\/\/blog.1oc.com\/?p=27\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-27","post","type-post","status-publish","format-standard","hentry","category-voip"],"_links":{"self":[{"href":"http:\/\/blog.1oc.com\/index.php?rest_route=\/wp\/v2\/posts\/27","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.1oc.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.1oc.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.1oc.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.1oc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=27"}],"version-history":[{"count":0,"href":"http:\/\/blog.1oc.com\/index.php?rest_route=\/wp\/v2\/posts\/27\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.1oc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=27"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.1oc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=27"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.1oc.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=27"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}