Saturday, February 14, 2015

Weekend Adventures in Coding - Visual Studo Customization - Order of Adornment Layers

When Visual Studio 2010 came out, I started looking into customizing the environment a little beyond what was able to be done with existing extensions. I was looking for the ability to place a background image underneath code and fix some issues with font rendering (particularly around the input font). I had succeeded in getting the background properties set through an extension I wrote (similar to ClaudiaIDE, but with a simple property set instead of adding an adornment layer -- it served my purposes but with some limitations). This morning, I tweaked my extension and brought it up to support 2013 (wow, was that easier than I expected!).

Font rendering was helped by re-running the OSes Clear Type configuration and installing Text Sharp. If this sort of thing is important to you, you also want this free gem: MacType. It causes Windows to render fonts in a way that is more similar to a Mac which I find improves readability substantially. Unfortunately, it doesn't work perfectly everywhere, but some of Visual Studio is affected.

I've decided today to see if I can apply the last bit, a white shadow to text. This is a common effect throughout MacOS/iOS and I find it improves readability (particularly for high-contrast backgrounds).

Here's what I'm looking to apply (apologies for formatting, I'll get the code formatter working again, soon).
item.Effect = new DropShadowEffect
            Opacity = 0.34,
            ShadowDepth = 9,
            Direction = 542,
            BlurRadius = 9,
Finding an efficient way to do this (preferably without having to hack about with Reflection) has been frustrating, but I've managed to apply all kinds of effects elsewhere while I was attempting to fill in the gaps of the documentation with some reverse engineering.
Default order of Adornment Layers
While poking about, I thought it might be helpful to know the order of the default adornment layers. I just started (re-)evaluating OzCode and it was picked up by the "Exp" (temporary debug instance), so some of these belong to that. I'm also on CU4 so any that aren't documented may belong to that (search PredefinedAdornmentLayers or hit F1 for the documented ones).

Difference Space
Inter Line Adornment
Intra Text Adornment
I have no idea what I'll be doing with these, but that's the fun of reverse engineering. If you have to do such a task, OzCode is very helpful. It allows searching the contents of objects through several layers and can surface interesting bits to play with. This is, of course, experimental and likely will break between updates, but they've made extending Visual Studio so easy, it's not that bad to tweak between updates/versions. More to come if I figure this out!

Saturday, February 7, 2015

Another chapter after 17 years

On to new things!
After 17 years, I have decided to resign my position at Level (3). 17 years. That's a lifetime in IT. I started at a small telecom located in Southfield, MI and ended up at an international telecom with a headquarters in Broomfield.
What a ride
I started as a desktop tech, within a half-year I was doing servers. Ultimately Allnet was purchased by Frontier, Frontier by Global Crossing and then the bottom fell out. For the remaining years until about last year, I worked for a company that was effectively a start-up in a very competitive sector. Layoffs every year were normal while Global Crossing struggled (and ultimately succeeded) with survival. Level 3 purchased Global Crossing in 2011. For 15 of those 17 years, I rode the wave down and for the last two I've been riding it back up. It was strange working for a company that was not operating in survival mode.
It was 17 years for me, but nearly every year I was given a new position, more responsibility and new and interesting projects. Mix in the fact that I was working amongst, what I considered to be, some of the best people in our industry.
Onto Development
I'd always been a programmer. I'm not sure why I took the ops route originally, but within two years I was writing code that was changing the way our employees worked and I knew right away that this is what I was made to do. I love it. Over the years I was given the freedom to code, experiment and learn. I quickly jumped on the C# bandwagon, missing the days of hacking about in C and Pascal/Delphi and fell in love. And I learned...
So why now?
After 17 years, I've discovered that it's time for me to move on. During my time at Level 3, I had the privilege of working on some special projects involving Lync and Office Communications Server. This was my first exposure to an API that I couldn't simply Bing (there's one for you, MS) a million answers from people who had just learned the API. The APIs I was working with were pre-release, but after release the situation wasn't much better. For some reason, I enjoyed this immensely!
What now?
I had sent my resume out to Modality, a Microsoft Partner and a company with a very successful business in the Lync space, earlier last year. This wasn't unusual for me. If someone mentioned a job that sounded interesting to me, I usually prepped my resume, took and interview and turned down the job. It's happened so many times over the years that I almost expected to make the same decision when Modality had a position available to me. After talking to the guys over there, much to my own surprise, my mind was made up.
I'll be a US based, "work from home" (I prefer remote) employee working for a company that sells services and software for an application that, since 2008, has been the reason I could work effectively as a remote employee for Global Crossing and ultimately Level 3. Being a part of a company that was an early adopter--eliminating all phones on PCs and replacing them with USB headsets and speakerphones was far less of an adjustment than anyone could imagine---was great for me. The quality and effectiveness of audio conferences suddenly made it possible to have a workforce that was distributed far and wide without losing much other than water-cooler conversation.
Farewell, my Level 3 coworkers and friends! You are among the best and many thanks for the help, support and just-plain-fun you've given me over the last 17 years.

Thursday, November 20, 2014

Watching a Delta Jet Land Directly Overhead from the Beach in St. Martin (Sunset Beach / Airport Beach)

I just returned from my vacation and am not yet ready to post the "big review" quite yet. But I had to share this. Earlier this week I wrote "Today, I had a plane pass over me so close, I could lick it."

Here's the video.  It doesn't do the experience justice.  At the end, you'll hear the roaring wind that's all around us. The phone's microphone is totally overwhelmed.  It was just neat!

If you're interested in doing this yourself, find any Eastern Caribbean cruise that visits St. Maarten/St. Martin island. Take a cab from nearly anywhere to Airport/Sunset Beach, the rates are set by the government, for us it was $20.00 USD for my wife and I to get there.  Watch a few puddle jumpers land to position yourself, and enjoy.

I'll post the other videos I grabbed from less ideal locations, but here's the best one:

Wednesday, November 5, 2014

How to fix T-Mobile Wireless (WiFi, not 3G) CellSpot / ASUS TM-AC1900 Port Forwarding Not Working

You try to forward ports on your new $25 deposit ASUS Wifi awesome-router and it doesn't work. Neither does UPNP. Or maybe it works but not for very long.
What's happening
Those clever folks at ASUS added a NAT acceleration capability. Unfortunately, as best I can tell, it basically does nothing much better than crash regularly. This is why you may have noticed that forwarding works occasionally after reboot. I, personally, found this to be very rare. I've also found that the NAT acceleration isn't noticed when it's disabled. I don't have Google internet, but I'm pulling 80/20 and the router is doing fine.
Go to LAN -> Switch Settings. It will probably hang. Worry not, your router probably just crashed. You likely lost internet. Give it a full minute and refresh.
Go to LAN -> Switch Settings. Set any setting that has the word Acceleration (or NAT) in it to Disabled. Your router will reboot and your ports will be forwarded.

Updated to include "why"

My AT&T U-Verse Nightmare - Going on Two and a Half Years with Broken U-Verse High-Speed Internet

Update 2: This, at least, sounds like a similar problem.

Update 1: I can't believe I'm saying this but Comcast to the rescue? I had a wonderful customer experience with a CSR, purchased Comcast service to replace my U-Verse TV at home until Comcast gets a digital line to my house. I'm told this will happen before the house gets its most use next summer! Also filled in some details...

The following is an account of my lousy experience as an unhappy customer of AT&T U-Verse (Specifically their High-Speed Internet DSL variant). It is accurate to the best of my recollection. This isn't one of those horror stories where the company bankrupted the victim or anything like that. It's just one of frustration and banging of heads into walls... I hope it will be entertaining and informative to you, dear reader, but I make no guarantees. This post is to get out my frustrations and hopefully plan a new solution to this problem. These are my personal opinions, and though my wife would probably agree with me, many others that associate with me may not. Don't blame them. I'll update with new information (or any adjustments as this was "from memory" as they come along).
The Lake House
No, this is not the movie. My family purchased a cabin up north. If this seems strange to you, you don't live in Michigan. Seriously, nearly everyone has one. These communities are, to say the least, underserved. For the most part they're a mix of rural and vacation property. My dad swore he'd never get a place up north. He did. We're really glad they did!
Of course, being the most technically savvy in the family, the first thing I reached for was Internet access and I was pleased to find that AT&T offered 12/1 Internet service! Woot! I'm on-call and knowing that I could actually WORK from up there if I had to was a pretty nice thing.
Never Ending Quest for TV
The first thing we started looking into was TV. No dice. Comcast is the cable provider and they're analog only. Up until very recently, they offered so few channels for the price ($45) it was an extremely bad value. This was coupled with the problem that they offered no internet.
A side note to cable/ISPs: When I call up and ask if you have service, ask for my address and verify, especially in small communities. Comcast's regional office was certain we could get digital service with internet. Not until digging down to the address was it realized that this was not possible.

Next was DirecTV/Dish. The property is very low lying, but in this area that's normally not a problem. The location of the property, however, makes it impossible to hit either satellite. There are some options but all involve installations that Dish/DirecTV installers are "forbidden from doing". Understandable, you don't need your employees dying to install service to your customers.
AT&T was out because the "U-Verse" branded service that they offer is really just slightly improved DSL from the early 2000s.
Hacking together a solution: VerseFinity
I've been a cord cutter for a long time, but my mom really likes to watch the news before going to sleep. Sleep habits are tough to break! My normal route of Netflix, Plex and Hulu would not suffice. My dad had purchased a Slingbox and since I have Comcast Business Internet at home, the bandwidth was sufficient between AT&T and my connection at home to share Plex and Sling with no issues. Couple an iPad and an Apple TV or Roku (we have both) and you have a slightly clunky, but totally usable solution. And two rather non-price-optimized bills.
The first sign of stupidity
At my home I have U-Verse TV. I have SD service and one box. It's getting service from AT&Ts IP network using a low-end DSL modem (SD service doesn't net you the nice one). It's plugged into a Sling Box that pushes the TV signal out Comcast to my AT&T U-Verse Internet up north. Interestingly enough, it's coming in on the very same model low-end DSL modem that it's being sent to in my home! So basically, AT&T does sell IPTV service up north, you just have to buy a house somewhere else, Business Internet from Comcast and U-Verse TV.
Trying to Right my DSL Past
I have had DSL service before, but this was around 2000-2001. At that point, almost all broadband installations were difficult, and almost all had problems after the fact. Eventually, however, they'd get fixed. My first trip around the DSL block in 2000 netted me an almost identical problem to what I'm experiencing. I ended up running a new wire in the house, fresh for the DSL connection and that resolved everything.
Knowing this, and knowing that I have a history of running cable (and all of the basic equipment to test such cables), I eliminated all of the existing home wiring. We were not planning on having home phone service up there--we're well served by all carriers on the property--so it was gone. It was replaced with one straight run from the source about 15 ft. CAT-6 cable with the pairs wired properly. My own equipment can tell me a lot.
The intermittent mess - Beginning in 2012
The service never worked reliably. From the day it was installed it dropped off intermittently (which got worse progressively). It'd do this for a minute, look like it was going to connect again, disconnect, reconnect and be stable for a few minutes to a few hours. All. Day. And. Night. I called tech support and they sent someone out quickly. He saw no problems. Great. None-the-less, he replaced the box on the outside of the house and cleaned up all of the connection points. He checked my wire. Clean.
Throughout the summer we disconnect a bit. We had TWO techs come out. One replaced the modem, one checked everything and did something ... I'm still not clear. Still magically the internet worked and didn't work... mostly not working. Toward the end of the summer we had another tech out because the connection was really flaky. He replaced the modem. It seemed fixed, briefly, but it returned. Again.
At the end of the year, I started noticing something I noticed with DSL service at a previous residence. When the weather would turn cold or rapidly change in temp, the modem would disconnect/reconnect continuously. Warm working days would give into freezing cold, barely 30-seconds of Internet between minutes of disconnection. There's little to do up north in November while waiting for a tech for 8 hours on a Saturday... at a $25 gas bill each time.
After 3 tech visits and 6 months of barely functional service, I'm getting frustrated.
I make one last arrangement in late November 2012. A tech visited and actually saw the problem on the line while visiting (it was easy to see, it was happening every ten minutes).
"Everything looks clean for a few minutes for a while then *BAM* thousands of errors."
He said it could be something related to the connection points on the wire all the way to the CO. As the wires expand/contract, they disconnect/reconnect. Look, I work in telecom, but I have nothing to do with the actual telecom stuff. I know a lot about communications equipment, networking, wiring ... It didn't sound exactly right, but it was better than the nothing explanations I'd been getting so far. The tech suggested that switching out the modem and switching the port at the CO might help.
Side note: This is where that explanation falls off. If the issue exists at a point where a wire connects with another wire "in the elements", I would expect that replacing/changing two things that reside in (I'm assuming) a temperature controlled environment isn't going to help. Nuts.
It might have worked?
The internet service seemed to come back for the remaining time that we were there. I suspected that it would still fail so I put a RaspberryPi up there to serve as a way to send small bits of data back and forth and record success/fail in Nagios.
When the issues with the home were handled, we returned to internet service that was just down. This was the first point at which I started yelling on Twitter/Facebook. I didn't do so to get any attention, I was just angry!
Social Media to the Rescue? Maybe?
I got attention with my Facebook post. Suddenly my phone is ringing and helpful, state-side, folks are assuring me that everything is going to be fixed. A person is coming up there tomorrow. You don't have to be there. They did. They discovered the need to send someone out.
I was assured during this time that everything was going to be handled. I'd be credited. I'd be well taken care of. We're very sorry, sir. (sir, me?).
I was told that they'd do a something-or-other "Home Run", which was described as "we'll just give you new wiring so that at least we know it's our stuff".
I was told they'd replace the modem. Again.
Upon calling to set up the appointment, I made the mistake of contacting regular customer service.
The second sign of stupidity
Evidently yelling on Facebook/Twitter gets you put into some sort of "Second-Class" tech support line. I say second class, because I am still not impressed, but compared to the way you're treated when you call the regular support line? Good Grief.
The difference between Second and Third Class Support
In second class, I get all of those things I was told I would get. I didn't really want any of them. I wanted working Internet. I knew my pristine wire and all of its connections were clean. The modem had been replaced. Twice. Good grief, AT&T, what a waste of money! None-the-less, I was getting it because it might just magically fix the problem. And I was getting it with apologies for the frustrating service experience I'd had thus far.
Not so when I called Third Class support. My very friendly but exceedingly unhelpful representative told me that modems aren't free nor is home wiring. The modem would be at least $200. I explained I didn't want it and that the "other guys" had set that up. I'm assuming AT&T uses some sort of ticketing system that falls very short of providing call center employees with useful information. This person should have known I was working with someone on an ongoing issue. I told the rep I'd try my hand at the phone number given to me in the e-mail. I did. My rep (names omitted even though they're probably internal-use aliases) assured me everything would be taken care of.
The tech came out, replaced the modem and inspected the line. He told me the wire was better than what he'd install and wasn't worth doing. It tests well. Again, he left me with the impression that he thought he fixed the problem but couldn't articulate what the problem was. And, look, the modem is connected again. And it's a different kind of modem! Interestingly enough, this one displays a giant statistics page.
I was bumped from one social media rep to another and basically lost. The internet service continues to go up and down and it's basically unusable during the winter. But this is what happens when you have one provider for a huge geographical area with extremely old equipment trying to somehow make it do magic.
I've surveyed my neighbors. Most of them have U-Verse. Most of them assume it's normal for it to disconnect. The ones that know it isn't gave up trying to get it fixed. It comes and it goes.
So when you hear that Broadband penetration is "x" in the United States, think of all of those areas that are about 30 miles away from a major city. In my rural cabin community, the survey indicates 12/1 service provided by AT&T. My guess is that needs a giant asterisk followed by "where it works at all and we don't just string you along until you give up complaining ..."
There are very few. AT&T is the provider of choice and if you pick someone else you're on their equipment anyway. There's Fixed Wireless provided by a few rural providers but the service is "five times the price and a tenth the speed". In addition, being on low lying property like that, the chances of getting a line of sight signal are nil.
I see the orange Comcast Digital cable and I have talked to folks in town that have Comcast Digital service and internet.
The last sign of stupidity
I'm actually hoping that Comcast moves into the area so that I get better customer service. Good God, what is wrong with the world?

That might not have been fair. I have been a Comcast Business Internet customer for 5 years and I couldn't be happier with their customer service. I have not, however, had great experiences with their residential service folks.

Wednesday, June 18, 2014

FIX: ORA-00911: invalid character in c# but seemingly nowhere else

I am not normally a developer who targets Oracle, but something recently required me to go down this rabbit hole. I'm the first to admit that I hate Oracle primarily because I lack experience with their dialect of Sql and ... well, Java (Ask toolbars and security issues, grrr). But I digress.
The world's most useless error message
I write this at least partially as a joke because the specific solution I'm going to propose was a fix for my specific problem but because of the ambiguity of this error message, your problem could be something entirely different. Basically, what the Oracle database query parser is trying to tell us is that out of the hundreds of characters in your command text, at least one of them (maybe more) is not a character that it should be. It is, instead, an invalid one. Most likely, you've smashed two keys at the same time and put an errant underscore after a parenthesis. Maybe it's an obvious problem. Or maybe, like me, your unfamiliarity with Sql*Plus combined with this obtuse error led you down the wrong path a few times.
Bad semicolon
There's something about the Oracle provider in C# that causes it to crap all over your statement if the last character in the command text is a semicolon. Note that I've only tested this in the ODP.NET (DataAccess.dll not ManagedDataAccess.dll) 12.x client. In my case, I assumed it was that strange looking colon in front of the variable names. Nope, colon: Good. Semi-colon: Not so much.

Wednesday, December 25, 2013

Part VI - The Ultimate Linux Home Router - SquidGuard - Internet Filtering


It's worth warning that perfect internet filtering is impossible. It's for this reason that parents who have older children often don't bother with it since it tends to filter out benign things. That said, I have young children with tablets that Santa bought them for Christmas. I've locked the tablets down rather thoroughly on their own--prohibiting the use of the browser without a password and using a simple tool to restrict YouTube access. I know, however, that there will be times that they'll need the browser and when they do, they'll be using a browser with most controversial subjects filtered out. Don't get me wrong, I'm not interested in Nerf(tm)ing up the internet and preventing them from seeing some of the realities of life. But when they need unrestricted access, I will be there supervising directly. When I can't, most of the internet will be blocked.

Run an update

Since it's been a few days since this was posted, it's worth making sure we're running the latest versions of everything. Run the following and follow any onscreen instructions.
$ sudo zypper up

Installing SquidGuad

$ sudo zypper in squidguard

Restricting Tablets - DHCP Reserved Addresses

One option (and certainly not the most bulletproof) is to set the tablets up with static IP addresses. This is really simple to get around if your children have any basic understanding of IP networking (or know how to wield google in their favor). In a later post, I'll be adding authentication to the proxy server, but until then, I wanted to at least force DHCP to assign the same address. The settings panel on my tablets is password protected, so one of the kids changing the settings is not a huge concern of mine. In addition, assigning the IP via DHCP ensures that I won't need to make other configuration changes when the tablet moves to different networks.
Reserved addresses are assigned when the DHCP server sees a client with a specific MAC address. Since it's easier to retrieve the current IP address on my tablets, I've written down the two addresses: and, and we'll look up the host details on the server.
The following command will display all of the current leases
$ cat /var/lib/dhcp/db/dhcpd.leases | egrep "(^lease)|(hardware)"
This will display all of your current leases and their MAC addresses. Find the one that matches what was assigned to the tablets and copy the hardware address.
$ sudo nano /etc/dhcpd.conf
Find the subnet that corresponds to your network. It'll look something like this:
subnet netmask {
  default-lease-time 14400;
  max-lease-time 172800;
Modify it:
subnet netmask {
  default-lease-time 14400;
  max-lease-time 172800;
  host girlstablet {
    hardware ethernet xx:xx:xx:xx:xx:xx;
I've added a host 'girlstablet', which has the MAC address "xx:xx:xx:xx:xx:xx" assigned it the address I'll be putting all of the restricted devices on the 192.168.0 subnet in the range Do the same with any other addresses, assigning them an IP address outside of the normal lease range.
Save and Exit, then run:
$ sudo rcdhcpd restart

Installing Blacklists

I'm going ot use Shalla's Blacklists for this example, but there are several others available. Shalla's is for private, non-commercial use only. If you're using it for a business, consult their web site to ensure you are compliant. Creating a script to download the filter list:
$ sudo nano /usr/sbin/update_squidguard_blacklist
Paste in the following and Save/Exit.

cd /var/lib/squidGuard/db
rm -r *
wget ''
tar -xvf shallalist.tar.gz
cd BL
mv * ..
cd ..
rmdir BL
/usr/sbin/squidGuard -C all
chown -R squid *
chown -R squid /var/log/squidGuard
rm shallalist.tar.gz
squid -k reconfigure
Run the following:
$ sudo chmod 750 /usr/sbin/
$ sudo ln -l /usr/sbin/ /etc/cron.daily/
$ sudo nano -w /etc/squidguard.conf
Remove all lines from the file below "logdir /var/log/squidGuard" and paste in the following:
dest adv {
     domainlist adv/domains
     urllist    adv/urls

dest aggressive {
        domainlist      aggressive/domains
        urllist         aggressive/urls
        log             aggressiveaccess

dest alcohol {
        domainlist      alcohol/domains
        urllist         alcohol/urls
        log             alcoholaccess

dest anonvpn {
        domainlist      anonvpn/domains
        urllist         anonvpn/urls
        log             anonvpnaccess

dest costtraps {
        domainlist      costtraps/domains
        urllist         costtraps/urls
        log             costtrapsaccess

dest dating {
        domainlist      dating/domains
        urllist         dating/urls
        log             datingaccess

dest drugs {
        domainlist      drugs/domains
        urllist         drugs/urls
        log             drugsaccess

dest gamble {
        domainlist      gamble/domains
        urllist         gamble/urls
        log             gambleaccess

dest hacking {
        domainlist      hacking/domains
        urllist         hacking/urls
        log             hackingaccess

dest porn {
        domainlist      porn/domains
        urllist         porn/urls
        log             pornaccess

dest redirector {
        domainlist      redirector/domains
        urllist         redirector/urls
        log             redirectoraccess

dest sexeducation {
        domainlist      sex/education/domains
        urllist         sex/education/urls
        log             sexeducationaccess

dest sexlingerie {
        domainlist      sex/lingerie/domains
        urllist         sex/lingerie/urls
        log             sexlingerieaccess

dest spyware {
        domainlist      spyware/domains
        urllist         spyware/urls
        log             spywareaccess

dest violence {
        domainlist      violence/domains
        urllist         violence/urls
        log             violenceaccess

dest webmail {
        domainlist      webmail/domains
        urllist         webmail/urls
        log             webmailaccess

dest webtv {
        domainlist      webtv/domains
        urllist         webtv/urls
        log             webtvaccess

dest warez {
        domainlist      warez/domains
        urllist         warez/urls
        log             warezaccess
acl {
        admins {
                pass all
        restricted {
                pass !weapons !warez !webtv !webmail !sexlingerie !sexeducation !redirector !porn !hacking !violence !aggressive !alcohol !anonvpn !costtraps !dating !drugs !gamble all
        default {
                pass !spyware all
Run the following command:
$ sudo echo 'redirect_program /usr/sbin/squidGuard' >> /etc/squid/squid.conf
$ sudo /usr/sbin/

Saturday, December 21, 2013

Part V - The Ultimate Linux Home Router - Services: SSH, Squid, Privoxy - Advertisement Blocking Network Wide

Secure Shell Server (SSH)

A Secure Shell server is a great utility to have accessible externally. At home, I use port forwarding through my SSH server for a variety of uses. On public Wi-Fi networks, I fire up my SSH client on my phone and setup my browser to use my home proxy so that I can surf encrypted on a public network. When I'm visiting my children's school, I use the secure shell server to bypass the exceptionally restrictive firewalls installed at US public schools (and not for evil things ... simple things like Facebook don't work!). By opening one port to SSH, I am able to access my entire home network and all of its services. I can remote into my desktop or laptop via RDP. I can issue commands to my Roku. I can copy files (using WinSCP) to and from the public or family PC I'm working on to any PC on my home network.

Securing Secure Shell

Running a Secure Shell server doesn't come without risks. It's a high value target for hackers. Brute force attacks are extremely common, and are even done in ways that reduce the probability of detection (such as very slowly trying multiple common passwords). I allow password authentication for Secure Shell and am not providing steps on eliminating that (because I simply don't care enough about it). I strongly recommend using a very complex passphrase (multiple words, punctuation, with numbers mixed in) to ensure a brute force attack is unsuccessful.

Reducing attack surface of SSH

We're going to do the following: Pick a non-standard port for SSH. You have two options, each with pros and cons:
  • Option 1 - Pick a common port, such as Port 80 or 443. This will not reduce your attack surface that much, since these ports are also commonly attacked, but since SSH will be running on that port and not the service the hacking tool is looking for, it may render the tool ineffective (probably not). The pros of picking a common port like 80 or 443 is that they're unlikely to be blocked egress on a firewall. Pick a common port if the most important thing to you is being able to access your SSH server from anywhere.
  • Option 2 - Pick an uncommon, random port like 3154 (well, don't use that now that I put it in this post ... actually, it probably won't matter, the traffic to this site is pretty miniscule).
I chose option 2 because, lately, I've rarely ran into a scenario where I couldn't access a random port egress on even Public School WiFi.
We're going to eliminate root logon. Allowing root login is a very bad idea. This ensures that the attacker needs to not only guess the password, but also the ID in order to log into your server.
Run the following:
$ sudo nano /etc/ssh/sshd_config
#Port 22
#PermitRootLogin yes
#MaxAuthTries 6
Port xxxx
PermitRootLogin no
MaxAuthTries 1
Where xxxx is the number of the port you selected above. Save and Exit.
Run the following:
$ sudo nano -w /etc/sysconfig/SuSEfirewall2.d/services/sshd
Change TCP="22" to TCP="XXXX" where XXXX is the port you selected above, then run:
$ sudo rcsshd restart
$ sudo rcSuSEfirewall2 restart
Replace xxxx with the port you selected above.

Reducing attack surface with DenyHosts

Denyhosts is a script that trolls the logs looking for authentication failures. When it finds a certain threashold of them from a particular host, it adds that host to the hosts.deny file which prevents the server from accepting connections from that host in the future. We're going to set the threshold pretty low, so you may end up locking yourself out by accident. If that happens, simply login from a different host and remove the host from hosts.deny.
$ sudo zypper ar --refresh 'openSUSE 13.1 Network Utilities'
$ sudo zypper in denyhosts
(be sure to answer "a" when prompted)
$ sudo chkconfig --level 3 denyhosts on
Worthy Note: Because DenyHosts is running on your router, having too many login failures on a machine within your network will not only block you from logging in with SSH, it'll block you from connecting to anything (including the internet). So login with caution!

Proxy Servers

I'm debating, for the time being, precisely which proxy to install. I've used Squid for years, but there are alternatives out there and, in fact, we're going to be using one of them -- privoxy. There's no reason they all can't coexist on the same machine, however, it may not be necessary to run more than one. We'll chain squid and privoxy together and later, when we want to child-proof certain things on our network, we'll add squidGuard to the mix.
Run the following:
$ su
(enter your password)
# zypper in squid privoxy privoxy-doc
# systemctl enable squid
# systemctl enable privoxy
# nano /etc/squid/squid.conf
http_port 3128
http_port 3128 transparent
# nano /etc/sysconfig/SuSEfirewall2
Hit CTRL+W and type "FW_REDIRECT" to get to the line.
# rcsquid start
# rcSuSEfirewall2 restart
Browse to something on the internet on Port 80 within your local network and you can "cat /var/log/squid/access.log" to see that the proxy is working properly. Once you're sure that's up and solid, we'll chain privoxy.

Configuring Privoxy for Advertisement blocking for your whole network

I won't get into the ethical arguments around blocking ads. I would love to trust publishers to give me advertisements that weren't filled with malware, but at present, I can't. It pains me even more that the two or three affiliate links I may use on this site won't work after you follow these instructions, but I won't be a hypocrite and complain about that. Here's a longer discussion on the subject This is why I adblock and you should too. If you feel evil doing this, you can simply skip this section. This is one of a few methods we're going to use to eliminate ads on our network. This will also reduce the ability of web sites to track your behavior. Occasionally, privoxy gets it wrong and blocks something useful, but I've been running it for months now and it works brilliantly. There are some things as of this writing that are broken about the privoxy package provided in the 13.1/Tumbleweed repositories. We're going to tweak the service definition and load the service to correct this. First we'll modify the configuration:
# nano /etc/privoxy/config
Locate the following lines (hint: CTRL+W)
logdir /log
confdir /etc
Replace them with:
logdir /var/lib/privoxy/log
confdir /etc/privoxy
Locate the following lines:
#debug 4096
#debug 8192
Replace it with:
debug 4096
debug 8192
# nano /usr/lib/systemd/system/privoxy.service
Remove all lines in that file and replace it with:
Description=Privoxy Web Proxy With Advanced Filtering Capabilities

ExecStart=/usr/sbin/privoxy --user privoxy --pidfile /var/run/ /etc/privoxy/config
ExecReload=/bin/kill -USR1 $MAINPID

Run the following commands
# systemctl daemon-reload
# systemctl start privoxy

Chaining Squid and Privoxy

Run the following commands:
# echo 'cache_peer parent 8118 7 no-query' >> /etc/squid/squid.conf
(configures privoxy as a parent to squid)
# echo 'acl ftp proto FTP' >> /etc/squid/squid.conf
# echo 'always_direct allow ftp' >> /etc/squid/squid.conf
(skips privoxy for FTP requests)
# echo 'never_direct allow all' >> /etc/squid/squid.conf
(uses privoxy for all other requests)
# squid -k reconfigure
To test, simply fire up a browser that doesn't have Adblock installed and visit a page (non-SSL) that has lots of ads. You'll also notice some of the ads are gone from your phone as well.

Blocking Ads via BIND DNS

As I mentioned earlier, privoxy is not fool proof. It does land itself into false positives from time to time. While putting this together, I discovered one of those cases. We'll need to get some files from a site for our BIND DNS blocking, but in order to do that, we have to first configure privoxy to whitelist the site.
# echo "{ -block }" >> /var/lib/privoxy/etc/default.action
# echo "" >> /var/lib/privoxy/etc/default.action
In a browser somewhere on your network, click this link and make sure it's not blocked. Then run the following commands:
# nano /usr/sbin/
Paste the following:
wget ';showintro=0' -O /etc/
cat /etc/ | egrep '^zone' > /etc/
rcnamed restart
Save and exit, then run:
# chmod 750 /usr/sbin/
# ln -s /usr/sbin/ /etc/cron.daily/


Corrected DNS ad blocking section. Added cron job for downloading DNS list.

Part IV - The Ultimate Linux Home Router - DHCP and Routing

Here's where we put it all together and finally replace our existing router. You might want to print this out because some of these steps will be done without internet connectivity.

Other things you may need to purchase

If your existing router also provided wireless access and you want that wireless access to remain behind the firewall (strongly recommended!), you'll need to buy a wireless access point. I love the Buffalo line of wireless routers because they run DD-WRT, an open-source, linux based router firmware. It's inexpensive -- $39 on Amazon, and with the routing capabilities disabled, you'll have a 4-port switch with wireless access. If your existing router allowed you to plug more than one device into it (and you're currently doing just that), you'll need to purchase a switch (unless you elected to buy the wireless access point with a switch). Here's the one I purchased

Preparing to replace your existing router - Figuring out the external side of the network

Option 1: Get rid of your existing router. Obviously you can't do this if your existing router is also your cable or DSL modem.
Option 2: Disable your existing cable or DSL modem's routing capability.
Option 3: Leave your existing router in place, disable all firewalling and setup your new router as a DMZ host.
You'll want to pick one of these. The steps for doing this vary depending on your existing hardware. I (currently) use Comcast Business internet and short of purchasing a static IP, I'm stuck with option #3. I've been running this way for some time now and it's not caused any problems other than having to remember I have one added bit of network complexity.

Setting up the External network

If you are using a USB external network adapter and have not yet plugged it in, plug it in (but leave the network cable disconnected).
$ su
(enter your password)
We could have sudo'd that, but we're going to be doing a lot as root to get this ready, so let's live dangerously.
Select Network Devices and Network Settings Select your external network adapter and choose Edit. On my setup, my external USB adapter is eth1. I'll be referring to eth1 a bit in the future as we issue commands from the shell. If yours has a different name (as it does on my other device), remember it and substitute it whenever you see eth1 in a command. If you picked option 3 above, you'll follow the directions for assigning a static, non-routable, IP address. If you picked option 1 or 2, you probably want to leave the external side as DHCP unless you were assigned or pay for a static IP from your ISP.

Getting the existing network settings

Determine the network that your existing router assigns addresses. If you have a windows box behind the firewall, you can drop to a command prompt and type "ipconfig /all". Locate the IP address assigned and the subnet mask to determine the address. In my case, the IP address is and subnet mask is (/24). This means that my existing router's network is Write down your DNS settings. Go to your router's configuration and locate the DHCP and LAN settings.

For Option 3 folks, only

Since we're already using an IP address on your router's existing internal network, we need to change the network that the existing router uses. I've switched mine to use (192.168.1.x network with a subnet mask of as the network and as the router's address. I've also disabled DHCP since I'll be assigning the external network address statically. Consult your router's manual on how to make these changes, it'll be different for everyone. Oh, and when you make these changes, you're going to disconnect yourself from the internet. Your current PC will have an address on a different network and won't know how to get to the gateway, so before you save your settings, make sure you're positive they're right. If you screw it up, consult your router manual on how to hard reset the router and try again.

Assigning a Static IP

If you have paid for a routable, static IP address from your ISP, find the documentation they gave you to identify the correct DNS, Gateway and IP address and Subnet Mask to assign here. If not, use the values you discovered from the previous section.
Select Statically assigned IP address, put in the address from your ISP or from what you selected above.
Select ubnet Mask, enter the value from your ISP or from what you discovered above.
Select Hostname. Use the same hostname you used during installation, but add a "-ext" to signify that this IP points to the external side of the router.
Select General and tab over to Firewall Zone. Select External Zone. This will cause the firewall to filter all unsolicited traffic that you haven't explicitly allowed. We'll be doing a lot more customization later.
Hit F10 to save these values.
Select Routing.
Under Default IPv4 Gateway, enter the value from your ISP or from what you discovered above. This is the dumb "if there is no other explicitly assigned route, use this one" route.
Put an [X] in the box next to Enable IP Forwarding.
Hit F10 to save these values.
Select Security and Users and then Firewall. Select Masquerading.
Put an [X] in the box next to Masquerade Networks.


Run the following:
# zypper in dhcp yast2-dhcp-server dhcp-server
# yast
Select Network Services then DHCP Server.
Select your internal network adapter, choose Select.
Make sure there's an X only next to the internal network adapter.
Select Open Firewall for Selected Interfaces. Choose Next.
On the next screen, choose Domain Name and enter the Active Directory domain name (
For Primary Name Server, Secondary Name Server, Default Gateway, and NTP Time Server, enter the IP address of the internet network adapter on your new router. Leave the rest blank.
For IP Address Range, select a range you'd like to assign to the pool. I used -
Under Service Start, select When Booting. Select "Next" and Quit.

Plug it all in

At this point, you need to unplug all of the ethernet cables from your router (If your router has an internet side that is Ethernet, unplug all ethernet cables except that one). Plug your external network adapter into the existing router. Plug the cables that were going to your existing router into a switch and plug that switch into the new router. If you have a relatively simple network and your ISP provided you with a router, your existing network probably looked something like this:
[INTERNET]=====| Router |=======[Computer]
               |  from  |=======[Computer]
               |  your  |=======[Xbox]
               |  ISP   |=======[Wireless Access Point]
It's now going to look something like this.
               /--------\    /---------\   /--------\
[INTERNET]=====| Router |====| Awesome |===| Switch |===[Computer]
               |  from  |    |   new   |   | or WAP |===[Computer]
               |  your  |    |  Linux  |   | with   |===[Xbox]
               |  ISP   |    | Router  |   | switch |===[Roku]
               \--------/    \---------/   \--------/
It's a little more complex. If you purchased a pure wireless access point that isn't a router and doesn't include a switch, you'll plug that into the switch. If you picked a combined unit that is switch and wireless, you'll have something similar to the above.

Refreshing your internal devices

The easiest way is to simply reboot. However, for Windows boxes, you can drop to a Administrator command prompt and type "ipconfig /release" followed by "ipconfig /renew". You should see that you've now been assigned an address from your linux router.

On the off chance you're using an AX88179 USB 3.0 Ethernet Adapter

The kernel module that supports this device is a little flaky, so we're going to install the reference driver. It can be found by searching here. Run the following:
$ su
(enter your password)
# zypper in kernel-default-devel kernel-devel kernel-source
# cd ~
# wget
# tar -xfv AX88179_178A_LINUX_DRIVER_v1.8.0_SOURCE.tar.bz2
# cd AX88179_178A_LINUX_DRIVER_v1.8.0_SOURCE.tar.bz2
# make
# make install

Tuning the Router

By default, Linux isn't tuned for routing large amounts of traffic. Most of the default settings are fine, however, if you use BitTorrent or any P2P, you'll discover right away the limitations of the default settings. Here are some settings I have applied to my router to improve streaming video and applications that create large numbers of connections. Most of these settings were adapted from sources that I googled. Some may be wildly wrong and may show my ignorance of the Linux networking stack.
$ su
(enter your password)
# echo 'ifconfig eth0 txqueuelen 10000' >> /etc/rc.d/after.local
(If your adapter isn't called eth0 and eth1, replace these with what the adapters are actually called)
# echo 'ifconfig eth1 txqueuelen 10000' >> /etc/rc.d/after.local
# nano /etc/sysctl.conf
Add the following to the bottom of the file (adapted primarily from Linux Network Tuning for 2013:
# Increase system file descriptor limit
fs.file-max = 100000

# Discourage Linux from swapping idle processes to disk (default = 60)
vm.swappiness = 10

# Increase ephermeral IP ports
net.ipv4.ip_local_port_range = 10000 65000

# Increase Linux autotuning TCP buffer limits
# Set max to 16MB for 1GE and 32M (33554432) or 54M (56623104) for 10GE
# Don't set tcp_mem itself! Let the kernel scale it based on RAM.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.optmem_max = 40960
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

# Disable TCP slow start on idle connections
net.ipv4.tcp_slow_start_after_idle = 0

# If your servers talk UDP, also up these limits
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1
Save and Exit.
# nano /etc/security/limits.conf
Add the following to the bottom of the file:
* soft nofile 100000
* hard nofile 100000

Very Optional - Map IRQ of Network Adapter to Specific Core

I was having some network problems related to UDP performance over a double NAT (though I didn't discover that until I did a myriad of packet captures). This was one of the steps I attempted while troubleshooting. It was a shot in the dark, and ultimately I left it out of my configuration. In case you're in the same spot, I thought I'd leave the instructions. After completing this section, you'll add a line to /etc/rc.d/after.local to run the script with the network adapter name and the core of the CPU you wish to tie it to. More comprehensive instructions are available here.
# nano /usr/local/bin/
Paste in the following:
#set -x

if [ $# -eq 0 ]; then
   echo "usage: INTERFACE [CPU#]"
   exit 1;


echo "Binding interface $eth"
pid=`pgrep irqbalance`
   if [ $? -eq 0 ];
       echo "irqbalance is running! Pid = $pid"
       echo "it will undo anything done by this script"
       echo "Please kill it and re-run this script"

num_slices=`grep "${eth}" /proc/interrupts | wc -l`
while [ $done != 1 ]
# one of the following, depending on which version of the driver is installed
   irq_data=`grep "${eth}:slice-${slice}" /proc/interrupts`

   if [ $? != 0 ];
       if [ $i != 0 ];
       irq_data=`grep "${eth}" /proc/interrupts`
       if [ $? != 0 ];
   irq=`echo $irq_data |  awk '{print $1 ; }' | sed -e 's/://g'`
   printf "Binding slice %2d to CPU %2d: writing mask 0x%08x to $file\n" $slice $mask $mask
   printf "%x" $mask > $file
   i=`expr $i + 1`
   slice=`expr $slice + 1`
   if [ $slice -eq $num_slices ];
Save and exit.
Run the following:
# chmod 750 /usr/local/bin/

Friday, December 20, 2013

Part III - The Ultimate Linux Home Router - Active Directory on openSUSE using Samba 4.1

Compiling the Latest Version of Samba 4

Samba 4 is the first version of Samba to adequately host Active Directory without the need for an expensive Windows Server. Though it's been in the wild for a while now, it's still got some rough points. I've been using it for a few months now and the only issues I've run into have been centered purely around Microsoft applications that require schema updates to function. I'm running it with a single domain controller, so I've not tried to get replication functional (this is, after all, just a home network).
There are samba packages in the Tumbleweed repository, but at this point in time they are not at the version I needed, so we'll be compiling from the source. Parts of this entry were adapted from Conrad Jones blog. Much thanks to him for publishing that. Run the following commands (make, gcc and binutils will already be present if you opted to install fish):
# zypper install make gcc binutils autogen krb5-devel krb5-client nano libacl-devel acl attr python python-devel
You may get a message indicating that python conflicts with patterns-openSUSE-minimal_base-conflicts, select to deinstall if this pops up.
# reboot
We need to reboot to ensure that the filesystem is mounted with ACL support. After reboot, login:
$ su
(Enter your password)
# cd ~
# wget
# tar -xvf samba-4.1.3.tar.gz
# cd samba-4.1.3/
# ./configure; and make; and make install
You may want to visit Samba's Website to find the latest version rather than using 4.1.3. They move pretty quickly over there (a samba server I just installed two weeks ago was 4.1.1).
After about ten minutes, you should be compiled and ready to start configuring Samba and creating your new Active Directory domain.
Note: If you're wondering why the compile command issued was ./configure; and... instead of ./configure &&..., && is one of a handful of things fish shell doesn't support. If you're going to switch your shell to fish long-term, keep that in mind when viewing articles that have linux commands embedded. The syntax above will work in fish and bash.

Creating Samba Service Definition

# nano /usr/lib/systemd/system/samba.service
Copy and paste the following into the editor:
Description=Samba AD Daemon
ExecStart=/usr/local/samba/sbin/samba $SAMBAOPTIONS
ExecReload=/usr/bin/kill -HUP $MAINPID
Hit Ctrl+O (Write Out) and Ctrl+X (Exit).
Now we'll create a symbolic link to the service and configure it to run at startup
# ln -s /usr/lib/systemd/system/samba.service /etc/systemd/system/samba.service
# systemctl enable samba

Installing BIND 9 (Optional, use BIND 9 backend)

Personally, I prefer to stick with BIND over the default SAMBA DNS. It's rock solid, configurable, and there's a ton of information on how to tweak it because it's so widely used. You can stick with the internal DNS implementation if you want (and it's certainly a lot fewer steps), but I elected to use BIND.
# zypper in bind

Edit the configuration files

Now we need to add some parameters to the existing named.conf.
# nano /etc/named.conf
Directly beneath options {, put the following lines:
        # BEGIN ---- Configuration Modifications
        auth-nxdomain yes;
        # NOTE: These are the DNS servers. I choose to use them instead
        #       of the ones provided by my ISP. They're available globally so they
        #       should work fine, however, if your ISP or router adds their own split-brain
        #       DNS (U-Verse typically does this to make it easy to connect to your
        #       router information page), you will not be able to connect to their
        #       custom DNS entries.
        forwarders {;; };
        allow-transfer { none; };

        # IMPORTANT: Change the below to point to values appropriate for YOUR home network.
        #            I used for my wired internal network and for
        #            my guest wireless restricted internal network.
        allow-query {

        # IMPORTANT: You should only EVER let hosts sitting on the non-internet side
        #            of your router allow recursion even if you allow queries from
        #            external networks!
        allow-recursion {

        pid-file "/var/run/named/";
        empty-zones-enable no;
        # END   ---- Configuration Modifications
A note about some ISP networks: I have an ISP that provides me with an actual router. Ideally, we want to set up that router to pass all traffic to this router and do nothing else with it (disabling all firewall features). Sometimes this is done in a way that results in your external network card receiving your actual public routable IP. Sometimes this is done by setting the external interface as a DMZ host. The difference between them is negligible. With my ISP, if I want to have this box actually get the public IP address, I have to pay for a static IP. So I opted to use the DMZ method. This matters for only one reason NEVER include the network that is internal to your ISP provided router in the allow-query or allow-recursion section.. If you do that, you're actually allowing the entire internet to query and recurse on your DNS server. If you want to allow querying, simply add the external network zone to the allow-query section, but definitely do not add it to the allow-recursion section.

Modify the localhost Zone Files

# rm /var/lib/named/
# rm /var/lib/named/
# nano /var/lib/named/
Paste the following into

$ORIGIN localhost.

@       1D      IN      SOA     @   root (
                        42              ; serial (d. adams)
                        8H              ; refresh
                        2H              ; retry
                        4W              ; expiry
                        1D              ; minimum

@       IN      NS      @
        IN      A
        IN      AAAA    ::1
# nano /var/lib/named/
Paste the following into

@       IN      SOA             localhost.   root.localhost. (
                                42              ; serial (d. adams)
                                8H              ; refresh
                                2H              ; retry
                                4W              ; expiry
                                1D              ; minimum

                IN NS           localhost.

1               IN PTR          localhost.
Fix permissions:
# chown named:named /var/lib/named/*.zone
# chmod 640 /var/lib/named/*.zone
Let's test the configuration:
# named -u named
Did you see nothing? Good. Otherwise, if you got an error, run through the configuration parts of this section again and make sure you set it up correctly.

Configuring for hosting services on our Internal network

Now that we're actually going to HOST something and we have DNS setup, we need to stop requesting DHCP addresses. We're going to ignore wireless for now. I currently have only one network adapter plugged in since my other is USB based and I don't need it quite yet, so I'll be referring to the only adapter that I have. If you're following along with this from Part I, you should only have one cable plugged in and that should be your plugged into your internal network.
# yast
Select Network Devices and then Network Settings.

You're on the Overview screen. Select the network adapter that represents your plugged-in Ethernet adapter and choose Edit.
Put an X next to Statically assigned IP Address and hit TAB
Set your IP address to the desired value and hit TAB. I'm using since .1 is commonly the router IP address.
Set your Subnet Mask and hit TAB. I'm using
Set your fully qualified host name. This will be the computer hostname and the domain name that corresponds with your DNS and Active Directory domain. Example:
Go to the General tab.
Make sure Assigned Interface to Firewall Zone is set to Internal Zone (unprotected)
Hit F10
Go to Hostname/DNS and select Name server 1
Set it to the IP address you assigned above.
Go to Routing and select Default IPv4 Gateway and set it to your current, functioning router's IP. Do the same for IPv6 if applicable.
Hit F10 and once.
... and ... it hangs (or disconnects)! You just changed your IP address. Reconnect, but use the IP address you just set.
$ su
(enter your password)
# chkconfig -s named on
# rcnamed start
# rcnamed status
You should see the status as active (running). Now we'll test localhost lookup:
# host localhost.
Using domain server:

localhost has address
And reverse lookup:
# host
You should see:
Using domain server:
Aliases: domain name pointer localhost.
And let's nslookup something.
# nslookup
You should get back results. If you do not, "nano /etc/resolv.conf" and make sure the line that says "nameserver" reads "nameserver" or whatever the IP address that you used for your server. Yast failed to update it when I updated the network settings. If it's different, change it, save it and try nslookup again

Provisioning our Active Directory Domain

We'll use samba-tool to provision the domain.
# /usr/local/samba/bin/samba-tool domain provision --use-rfc2307 --interactive
You'll be prompted for values. Most should be the defaults if you've been following the configuration since Part 1.
 Server Role (dc, member, standalone) [dc]:
Administrator password:
Retype password:
Make sure to set the DNS backend to BIND9_DLZ

Updating BIND configuration to include samba entries

# nano /usr/local/samba/private/named.conf
Put a "#" in front of the 'database "dlopen /usr/local/samba/lib/bind9/"' and remove the "#" from 'database "dlopen /usr/local/samba/lib/bind9/"'.
Save and exit.
# nano /etc/named.conf
Add the following to the top of the file:
include "/usr/local/samba/private/named.conf";
Save and Exit.
And finally, we have to prevent BIND from running chrooted so that it can find the file.
nano /etc/sysconfig/named
Change the line that reads NAMED_RUN_CHROOTED="yes" to NAMED_RUN_CHROOTED="no".
# systemctl start samba
# rcnamed restart
# rcnamed status
You should see that the server is running. Now let's check that the samba entries have been created:
# host -t SRV
You should see: has SRV record 0 100 389

Configuring Kerberos and testing your new domain

We need to be able to get kerberos tickets, so we're going to configure the kerberos client and give it a test.
# cp /usr/local/samba/private/krb5.conf /etc/krb5.conf
# kinit administrator@YOURDOMAIN.NET
(enter the password you provided in the samba-tool step above
The capital letters are not optional. You should see a message about your password expiring in several days. Now, let's see if you have a ticket.
# klist
You should see a ticket in the list with a start date, expiration date and a renew until date that corresponds with the user you entered in the kinit statement above.

Configuring your server to backup your Active Directory environment

Especially since Active Directory support in Samba is relatively new and has bugs being fixed constantly, it's a good idea to have a backup because you'll probably be applying updates. And the fact that an AD domain is something that's usually in a state of flux, it's a good idea to get that started now.
# cp ~/samba-4.1.3/source4/scripting/bin/samba_backup /usr/sbin
# chown root:root /usr/sbin/samba_backup
# chmod 750 /usr/sbin/samba_backup
# mkdir /usr/local/backups
# chmod 750 /usr/local/backups
# ln -s /usr/sbin/samba_backup /etc/cron.daily/samba_backup
# nano /usr/sbin/samba_backup
Find the part of the script that looks like this:
                for ldb in `find $relativedirname -name "*.ldb"`; do
                        tdbbackup $ldb
                        if [ $? -ne 0 ]; then
                                echo "Error while backuping $ldb"
                                exit 1
Change the "tdbbackup $ldb" line to this (you can also add samba to your path, however, this guarantees the script will execute properly without the path variable set).
/usr/local/samba/bin/tdbbackup $ldb
Test the backup:
# /usr/sbin/samba_backup
# ls /usr/local/backups
samba_backup should return silently after running for a second and you should see files "etc..tar.bz2", "samba4_private..tar.bz2", and "sysvol..tar.bz2". If you ever need to restore, follow the instructions on the Samba Wiki.