One of the things I love most about SuSE is how well it integrates with Active Directory. Joining a domain is easy when using yast. First I ensured that the Linux server's DNS server is pointed to my DC, then yast -> Network Services -> Windows Domain Membership.
install yast's samba client module by executing zypper in yast2-samba-client.
Once I successfully joined my domain, I downloaded Microsoft ODBC Driver 11 for SQL Server - SUSE and ran the installation as directed. Something I really love about this ODBC driver for Linux is that I found it it also comes with sqlcmd and bcp. SQL Server data import/export from Linux? Whaaat!
Now, when I initially attempted to run isql, I received the following error:
[unixODBC][Driver Manager] Can't open lib '/opt/microsoft/msodbcsql/lib64/libmsodbcsql-11.0.so.2260.0' : file not found
After confirming that the file existed, I ran ldd to check for required libraries that may be missing.
suse:~ # ldd /usr/lib/libmsodbcsql-11.0.so.2260.0
libcrypto.so.0.9.8 => not found
libdl.so.2 => /lib64/libdl.so.2 (0x00007fcf8fb44000)
librt.so.1 => /lib64/librt.so.1 (0x00007fcf8f93c000)
libssl.so.0.9.8 => not found
libuuid.so.1 => /usr/lib64/libuuid.so.1 (0x00007fcf8f736000)
libodbcinst.so.1 => /usr/lib64/libodbcinst.so.1 (0x00007fcf8f525000)
libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x00007fcf8f251000)
libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x00007fcf8f011000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fcf8ed0b000)
libm.so.6 => /lib64/libm.so.6 (0x00007fcf8ea0d000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fcf8e7f6000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcf8e5da000)
libc.so.6 => /lib64/libc.so.6 (0x00007fcf8e22d000)
libltdl.so.7 => /usr/lib64/libltdl.so.7 (0x00007fcf8e022000)
libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x00007fcf8ddf9000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fcf8dbf5000)
libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x00007fcf8d9ea000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fcf8d7e6000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fcf8d5cf000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fcf8d3ae000)
Looks like I don't have the right version of libcrypto and libssl installed. Let's fix that:
suse:~ # zypper in libopenssl0_9_8
Now that we've got all the required libraries, we need to modify /etc/odbc.ini and /etc/odbcinst.ini. Here, I'll create a DSN entry called mydsn and use it to connect to the test database on sqlservera.base.local.
suse:~ # cat /etc/odbc.ini
Driver = ODBC Driver 11 for SQL Server
Database = test
Server = sqlservera.base.local
Trusted_Connection = yes
And the other
suse:~ # cat /etc/odbcinst.ini
[ODBC Driver 11 for SQL Server]
Description=Microsoft ODBC Driver 11 for SQL Server
So now I login using a Windows Domain account that has privleges to the SQL Server and the test database.
login as: base\chrissy
Using keyboard-interactive authentication.
Have a lot of fun...
BASE\chrissy@suse:~> isql -v mydsn
| Connected! |
| sql-statement |
| help [tablename] |
| quit |
It works! I'm genuinely surprised that it was so easy. Now to attempt to connect to my AlwaysOn Availability Group. I changed the server from sqlservera.base.local to sqlserver.base.local and attempted to connect:
BASE\chrissy@suse:~> isql -v mydsn
[S1000][unixODBC][Microsoft][ODBC Driver 11 for SQL Server]Cannot generate SSPI context
[S1000][unixODBC][Microsoft][ODBC Driver 11 for SQL Server]SSPI Provider: Server not found in Kerberos database
[ISQL]ERROR: Could not SQLConnect
Well, damn. Maybe I'm missing something? I browse ODBC Driver on Linux Support for High Availability, Disaster Recovery, Welcome to the Microsoft ODBC Driver 11 for SQL Server on Linux and the fabulous guide Securing Access to SQL Server from Linux with Kerberos, and using the information I found, I first try taking Microsoft's advice and connect sqlcmd using the -E option, which explicitly directs sqlcmd to "Use trusted connection, integrated authentication."
BASE\sqlserver@suse:~> sqlcmd -D -S sqlserver -E
Sqlcmd: Error: Connection failure. ODBC Driver for SQL Server is not installed correctly. To correct this, run ODBC Driver for SQL Server Setup.
Fail. Next, I try sqlcmd with the -M option to connect using the MultiSubnetFailover option.
sqlcmd: 'M': Unknown Option. Enter '-?' for help.
I then try to add the MultiSubnetFailover to the odbc.ini options and nothing. Maybe it's my Kerberos config? I enter a whole bunch of stuff using setspn, then confirm everything is fine using Microsoft Kerberos Configuration Manager for SQL Server and still nothing. At this point, I'm thinking it's a bug.
Firesheep got me thinkin' that I should probably do a little more to beef up the security of my Internet connection on public networks. PPTP has always been a favorite of mine, because it hides traffic well enough to deter most people and it's easy to setup on both Linux and Windows. I ran a Windows PPTP server for years, but recently decided to just host the service my WRT54GS v3 router running OpenWRT. Three hours later, I've got it running smoothly. Here's how I did it:
First, I installed and setup OpenWrt Backfire 10.03 and set my internal IP pool to be on the 172.16.x net, with the gateway (OpenWRT router being 172.16.1.1). Then, I headed over to OpenWRT's PPTPD HOW-TO.
opkg install pptpd
opkg install kmod-crypto
opkg install kmod-mppe
I believe my /etc/ppp/options file doesn't have any modifications, but just in case, this is what it looks like:
Now that I think about it, very few modifications were ultimately made to /etc/ppp/options.pptpd
# Otherwise, your chap-secret file will have to include "DOMAIN\\user" instead of user.
If you compare this to the original file, you'll notice I deleted the entry "172.16.1.1:" at the top of the file, and added the entry: ms-dns 172.16.1.1. I don't know why, but DNS didn't work well when the the client's defaults were used so I forced them to use the router's LAN DNS server.
Then I added some users to the /etc/ppp/chap-secrets file. I'll paste the contents, then go over the details. Oh, and don't forget to chmod 600 /etc/chap-secrets because the file's perms are insecure by default:
#USERNAME PROVIDER PASSWORD IPADDRESS
iphone pptp-server suprAdv4ncedPwd! 192.168.80.1
ipad pptp-server rlyAdv4ncedPwd! 192.168.80.11
hackbook pptp-server megaAdv4ncedPwd! 220.127.116.11
windows pptp-server ttllyAdv4ncedPwd! 192.168.80.2
extra pptp-server megaAdv4ncedPwd! 18.104.22.168
The chap-secrets file alone suggests that OpenWRT/PPTP is not an enterprise solution. I wouldn't propose it for any company with a decent budget, but times are tough and ghetto is looking better than ever to many companies.
I would actually have fewer entries in this file if the IPADDRESS field was not such a big issue. Unfortunately, it seems that the DHCP pool has been compiled into the service. It sets up the router's pppN to be 192.168.0.x and assigns the clients a 192.168.1.x address by default. Which is unfortunate, because SO DOES EVER OTHER RESIDENTIAL ROUTER, EVER. So routing issues keep pop up. Because of that, I force PPTPD to assign each user a specific IP, in the 192.168.80.x range because I've never seen any router use that subnet.
The usernames are whatever you'd like them to be (I made them the name of my devices) but if you are dialing-in from a Windows machine, you will have to preface the username with the Windows domain name or the name of your workstation if you are not on a domain UPDATE: adding chapms-strip-domain to options.pptpd fixes this. The "pptp-server" is what the service was named in options.pptd, the password is just that, and the IPADDRESS is the IP that the given client will be assigned.
Initially, my /etc/firewall.user didn't have all the proper entries, so my client was able to authenticate and all that, but no traffic was being routed to the 172.16.x subnet, nor was it being routed to the Internet. Here's what worked:
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
iptables -A input_wan -p tcp --dport 1723 -j ACCEPT
iptables -A input_wan -p gre -j ACCEPT
iptables -A input_rule -i ppp+ -j ACCEPT
iptables -A forwarding_rule -i ppp+ -j ACCEPT
iptables -A forwarding_rule -o ppp+ -j ACCEPT
iptables -A output_rule -o ppp+ -j ACCEPT
The first block allows clients to connect to the PPTP service and the second one allows it to communicate with both the Internet and the local network. And voila, you are done. I know it seems straightforward and doesn't deviate much for the default install, but it took over three hours of trial and error to get here. I've logged in successfully with an iPhone (over 3G, EDGE and wifi), an iPad, a Windows 7 machine and Mac OS X. The iPhone is of special importance to me -- after connecting to a local coffee shop's unsecured network on my laptop and my iPhone, I successfully hijacked my iPhone's Facebook app session using FireSheep. So, now I'll be encapsulating all of my traffic by sending it over to the fiber connection at my office, what what.
Next up, I'll probably start playing around with the RADIUS plugin. Stay tuned.
Earlier today, a colleague told me that she doesn't like using my servers because I don't have FTP setup thus, she couldn't map my server as a drive. Well, I showed her. I stand firmly against using FTP as any type of web-related solution and thus, decided on WebDAV to address my colleague's demanding needs.
Initially, I set the virtual host up for Basic Authentication but was unable to get Windows 7 and Windows XP to map the drive. Windows complained that "The network path could not be found." I tried mapping the drive from both the command line and from Windows Explorer with no luck. Then I read that theWindows webDAV client does not support Basic Authentication. If this server were on my domain, I'd use Kerberos without a second thought, but it's an Internet web server so that is out of the question. Digest Authentication it is.
I went enable mod_dav, mod_dav_fs, and mod_auth_digest in YaST under Network Services >> HTTP Server >> Server Modules and I restarted the service. I then created the folder /var/davlock, gave it the proper permissions and added the following to httpd.conf
Then I added the new host, sample.acme.com to my vhosts.conf file and restarted the service.
CustomLog /var/log/apache2/sample-access_log combined
Options Indexes FollowSymLinks
Allow from all
#Auth in the house
<limitExcept GET HEAD OPTIONS POST>
Allow from all
Notice AuthUserFile /etc/apache2/.htdigest. That file was created using htdigest2 (or on most other systems, htdigest).
htdigest2 -c /etc/apache2/.htdigest sample acmeuser
The -c switch creates the file, "sample" correlates with the AuthName directive and acmeuser is the username of my demanding colleague. Also take note that the way I used LimitExcept allows all non-webDAV users to have anonymous access to the site, while any webDAV activity requires a username and password.
Next, I mapped a drive in Windows with the two methods I am familiar with. First, via the command line
W:\>net use * http://sample.acme.com
Enter the user name for 'sample.acme.com': acmeuser
Enter the password for sample.acme.com:
Drive X: is now connected to http://sample.acme.com.
And then via Windows Explorer (My Computer >> Map Network Drive [be sure to click "Connect Using Different Credentials"]). Both worked flawlessly. And of course, this is all better if you can do it over HTTPS, which I plan to setup when I have time. But for now, my servers are totally in style and ready for use by people who aren't fans of vi .
Just a handy little reference for myself.
#Internal PPTP Server
iptables -N pptp
iptables -A pptp -p tcp --destination-port 1723 --dst $vpnserver -j ACCEPT
iptables -A pptp -p gre --dst $vpnserver -j ACCEPT
iptables -I FORWARD -j pptp
iptables -t nat -N pptp
iptables -t nat -A pptp -i $WAN -p tcp --dport 1723 -j DNAT --to $vpnserver
iptables -t nat -A pptp -i $WAN -p 47 -j DNAT --to $vpnserver
iptables -t nat -A PREROUTING -j pptp
### Gateway Router-based IPSEC VPN
# allow IPSEC
iptables -A input_rule -p esp -j ACCEPT
# allow ISAKMP
iptables -A input_rule -p udp -m udp --dport 500 -j ACCEPT
# allow NAT-T
iptables -A input_rule -p udp -m udp --dport 4500 -j ACCEPT
# disable NAT for communications with remote LAN
iptables -t nat -A postrouting_rule -d 172.16.0.0/24 -j ACCEPT
# Allow any traffic between tunnel LANs
iptables -A forwarding_rule -i $LAN -o ipsec0 -j ACCEPT
iptables -A forwarding_rule -i ipsec0 -o $LAN -j ACCEPT
Recently, I used my Windows-based domain's Enterprise Root Certification Authority to secure my subversion repository that is hosted on an Apache-based server. The process was rather straight-forward and relatively fast -- especially because I skipped over all of the file transfers and just used vi/notepad to copy/paste all the key info. The first step in this process is to generate a server key on the Linux machine:
ariel:~ # openssl genrsa -des3 -out ariel.corp.netnerds.net.key 1024
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
Enter pass phrase for ariel.corp.netnerds.net.key: **********
Verifying - Enter pass phrase for ariel.corp.netnerds.net.key: **********
Next, I used the key to create a certificate signing request
ariel:~ # openssl req -new -key ariel.corp.netnerds.net.key -out ariel.corp.netnerds.net.csr
Enter pass phrase for ariel.key: **********
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:LA
Locality Name (eg, city) :Kaplan
Organization Name (eg, company) [Internet Widgits Pty Ltd]:netnerds
Organizational Unit Name (eg, section) :IT
Common Name (eg, YOUR name) :ariel.corp.netnerds.net
Email Address :firstname.lastname@example.org
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password :
An optional company name :
Next, I concatenated the contents of ariel.corp.netnerds.net.csr and copied that into my clipboard. The request looked something like this:
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
I then opened up my domain's CA @ http://windowsCA/certsrv and went to
- Request a certificate
Or, submit an advanced certificate request.
- Submit a certificate request by using a base-64-encoded CMC or PKCS #10 file, or submit a renewal request by using a base-64-encoded PKCS #7 file.
- Saved Request:
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
Certificate Template: Web Server
Note: Be sure to decline when prompted by the browser to install the certificate locally.
I then opened the file in notepad, and copied the contents back into Linux as temp.key. In order to avoid having to type the passphrase in each time Apache is restarted, I decoded the key and moved that to the Apache directory.
openssl rsa -in temp.key -out ariel.corp.netnerds.net-decoded.key
Next, I copied the files into the appropriate directories in /etc/apache/ssl* and modified my /etc/apache2/vhosts.d/vhost-ssl.conf and added the appropriate file locations:
Finally, I restarted the apache service and then partied to Wayne Toups.
Some things just belong on Linux. Like Subversion and Apache, for instance. I've seen the ghetto workarounds for Windows-based Apache installs and no thanks -- I'd much rather waste my time on ghetto SharePoint workarounds.
But I sure do like the way Windows-based web servers such as IIS seamlessly and securely authenticate users across a domain. I wanted Apache to do the same and, after a week of trying various methods of authentication, I found the easiest, most efficient way is to use SSL, Kerberos, and Likewise.
I start this project, as I do all of my Linux projects, by using a fresh install of SuSE Linux Enterprise Server (SLES 11). During the initial install, I made sure to use a local passwd file for authentication. Likewise takes care of all the advanced authentication methods after the install is complete. When using Likewise, do not attempt to use YaST to configure authentication or you'll run into a variety of pam and krb5 key issues.
Here are the following steps and tutorials I used to accomplish my goal of SSO
- Install and configure Likewise Open.
- Joining a domain is as easy as /opt/likewise/bin/domainjoin-cli join corp.netnerds.net Administrator, even when authenticating against Windows 2008 Active Directory.
- Setup Apache to support SSL
- Setup Apache to support Kerberos-based SSO
- My ktpass, for example, looks like this:
ktpass /out http.ktb /princ HTTP/ariel.corp.netnerds.net@CORP.NETNERDS.NET /pass SkiAlta2009 /mapuser corp\linuxweb
- My ktpass, for example, looks like this:
- Install the One-Click Installer that comes with OpenSuSE by default, but not SLES 11.
- yast -i yast2-metapackage-handler
- Add the subversion packages to the local repository.
- OCICLI http://software.opensuse.org/ymp/Subversion/SLE_11/subversion.ymp
- Go into YaST and install the necessary subversion packages.
- Follow the OpenSuSE tutorial for Setting Up a Subversion Server Using Aapache 2
- Throw a party! Just turn up Pandora's Cajun station and DANCE.
I recommend using your domain's own Certificate Authority to generate the SSL cert that Apache will use. That way, users won't be prompted to accept an untrusted self-signed SSL certificate.
This was ridiculous. Since apache-devel isn't available in SLES (and I do understand why, but give me the option at least!), I had to sync up one of my SLES machines to an OpenSuSE repository and get all of my necessary packages required to compile mod_auth_pam. I was required to downgrade quite a few packages, but whatever works, eh?
For those of you running SLES and are trying to get mod_auth_pam to work, you can grab a precompiled copy of mod_auth_pam.tgz.
This works on the standard Apache2 install that comes with SLES 11. I presume it also works on OpenSuSE 11 as well. Just download the tgz, extract the contents, and run ./install. Then you can load up Novell's step-by-step tutorial on how to get this to work. Take note at the instructions to manually change a few files because that still needs to be done.
For my future reference, here are the Apache directives I ended up using:
While this works, it isn't seamless like way mod_auth_ntlm_winbind, but it works over SSL, unlike mod_auth_ntlm_winbind.
Thank Science for SuSE Linux Enterprise 11; it's made this process relatively easy. SLES 10 SP2 was giving me a headache because of some Windows 2008 based Active Directory authentication issues but upgrading SLES 11 took care of all that.
First thing is first, setup samba to authenticate to AD. Next, install the OpenSuSE mod_auth_ntlm_winbind RPM.
rpm --install http://download.opensuse.org/distribution/11.0/repo/oss/suse/i586/apache2-mod_auth_ntlm_winbind-0.0.0.lorikeet_svn_682-135.1.i586.rpm
The wiki for this Apache 2 module can be found here. Next, we're going to instasll pam_smb, set the proper permissions on winbindd_privileged, add the module to apache and restart the web service.
yast -i pam_smb
setfacl -m u:wwwrun:rx /var/lib/samba/winbindd_privileged
Finally, add something to the effect of this to your Apache config file:
<directory " /srv/www/htdocs">
AuthName "NTLM Authentication"
NTLMAuthHelper "/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp"
Restart the service and you should be authenticating automatically. Don't forget to add the website to your browser's Intranet zone if needed.
Also, I read that, unfortunately, auth_ntlm_winbind, doesn't work over SSL but I'm going to try it anyway. In the event that it doesn't, I'll be exploring Kerberos authentication within Apache.
Well that couldn't have been easier! Here's all it takes to authenticate SLES 11 to Windows Server 2008 based Active Directory. During the initial install of SLES, I performed the following:
- Selected samba-client and winbind during the software installer phase
- Added my domain's DNS servers to the intitial network config using NetworkManager
- Ensured I had the right DNS search suffix (the name of my domain: base.netnerds.net)
Surprisingly, I didn't even have to configure samba after my install was completed. I was prompted to join the domain during the initial OS install and everything went as expected. Here are the settings I used:
I logged in using the domain\username format and this too, worked as expected:
login as: base\chrissy
Using keyboard-interactive authentication.
Creating directory '/home/BASE/chrissy'.
Creating directory '/home/BASE/chrissy/bin'.
Creating directory '/home/BASE/chrissy/.fonts'.
Creating directory '/home/BASE/chrissy/.mozilla'.
Next up, setting up NTLM pass-through authentication in Apache!
Update: If you plan to use Kerberos, I recommend you skip straight to using Likewise for all of your authentication needs. I had nothing but headaches from reported bugs with SuSe's built-in Samba and krb5/Kerberos.
IBM DB2's free version "DB2 Express-C" is available for download at db2express.com. So far, I've successfully installed and uninstalled DB2 Express on SLES 10 SP2. While there was a command line installer included (db2_install), the server wouldn't start after a supposedly successful install. I figured I would have to use the GUI install, but my SLES instance doesn't run X-windows so I had to download X-Win32 and export my display (export DISPLAY=cracklin:0.0) to my laptop and go from there.
Administration of DB2 Express-C is performed using IBM Data Server Client (registration required), which also includes the IBM DB2 OLE DB drivers needed to create a DB2 linked server in SQL Server.
After working with the Server Client (which contains the Control Center, DB2's equivalent to SQL Server's Enterprise Manager), I wanted to reinstall DB2 with different parameters, specifically the administrator account and the TCP port. DB2's default port is 50000 but the Linux install sets it to 50001 for some reason. I can probably change this using the built in command-line tools but I didn't want to invest to time to track it down, so I uninstalled DB2 and reinstalled the server by executing the following:
chmod +x /opt/ibm/db2/V9.5/instance/*
chmod +x /opt/ibm/db2/V9.5/bin/*
chmod +x /opt/ibm/db2/V9.5/adm/*
chmod +x /opt/ibm/db2/V9.5/das/bin/*
rm -rf /opt/ibm/db2
Then I reinstalled with a whole new perspective on the way things work. If you're interested in what the IBM Control Center looks like, here's a sample from my own environment (Windows client, Linux server).
Click to enlarge.
So far, so fun