My project du jour is getting updating the firewall for the lab from RedHat 8 to Fedora Core 3. We are doing a Linux install for the lab so we can have a training toward the end of the month.
The firewall will actually be serving several important functions for the lab:
Actually installing the system was something of a challenge.
    I've got the ISO images, but no blank CDs. I used a funky HTTP install for the
    machines in the lab, but the firewall only has 32mb of RAM and the
    FC3 installer refuses to run. So, I had to actually pull the drive
    and run the install in another box and then move it back.
    Disappointingly, the support for the ISA network cards which were
    auto-detected in RedHat 8, did not work in FC3. I had to go in and
    edit /etc/modprobe.conf by hand.
After some mucking about thought I managed to get it up and running. It was not horrible, but the number of problems I had definitely would have thwarted almost any novice:
Finally though it was up and running with all the hardware working.
My little lab is NATed away from the rest of the university. We didn't used to be this way, but students here are frequently changing the IP addresses as a part of the course and though I emphasized the importance of being careful, they weren't. The university admins got frustrated with it and eventually stuck us off on our own. I prefer this solution to the previous one, which was simply to unplug our lab from the main switch.
The NAT was quick and simple: (we are
    192.169.99.0/24 and the uni is
    192.168.2.0/24)
iptables -t nat -A POSTROUTING -s 192.168.99.0/255.255.255.0 -j SNAT --to-source 192.168.2.176 service iptables save
There is also a server for the Cisco curriculum and a SMB fileserver at
    192.168.99.250. I wanted that traffic to pass
    through, so I also did:
iptables -t nat -A PREROUTING -d 192.168.2.176 -p tcp -j DNAT \
    --dport 80 --to-destination 192.168.99.250
iptables -t nat -A PREROUTING -d 192.168.2.176 -p tcp -j DNAT \
    --dport 138:139 --to-destination 192.168.99.250
iptables -t nat -A PREROUTING -d 192.168.2.176 -p udp -j DNAT \
    --dport 138:139 --to-destination 192.168.99.250
service iptables save
    
    The DNS servers provided Mauritel are fairly unreliable. For this reason and to provide dynamic DNS in conjunction with the DHCP, I wanted to run a DNS server.
The setup is simple enough. I added a couple zones (forward and reverse) to the
    chroot jail
    at /var/named/chroot/var/named/ for the local
    addresses in the lab and then added the shared dyndns stuff to
    /etc/named.conf.
This was the first place I hit a snag. Something new in FC3 was the integration of Security Enhanched Linux (SELinux). I've never used it before and it was denying access to the new zones that I'd created.
The problem with traditional Linux security is granularity. There are normal users and there is root and the layering of protections between them is pretty slim. For instance, to run a program like Apache, I have to be able to bind port 80. To do so, the process has to be running as root. Another term for root is the "superuser" and while running as root I embody that term in a Nietzscheian übermensch kind of way. I can look at or delete anyone's files I want to. I can send out forged emails or sniff network traffic. I am above the law and only bounded by my capabilities and imagination.
The process that is normally used is to mediate this problem is that the Apache process will essentally give up its Godhood and become a normal user after it has done whatever it needed to do. This process though has its problems, mostly inherent in having to trust Apache. A better solution would be to be able change the environment so that Apache was only given limited power in the first place so even if it is made to misbehave, it can't do any harm. This is what SELinux begins to provide.
All subjects (users, programs or processes) and objects (files and devices) are now assigned identities, roles and types. There are security policies which are made based on those attributes.
The error I am getting when I try and start named is:
audit(911588074.103:0): avc:  denied  { read } for  pid=15535
   exe=/usr/sbin/named name=named.conf dev=dm-0 ino=267969
   scontext=root:system_r:named_t tcontext=root:object_r:user_home_t tclass=file
    If I just look at the file permissions, everything seems fine:
ls -l named.conf* -rw-r--r-- 1 root named 1547 déc 12 2004 named.conf -rw-r--r-- 1 root root 1329 nov 20 02:10 named.conf.orig
The file is readable by the named user who is what
    the bind process is running as. When we look at the SELinux
    contexts though, we can see the problem. (The programs
    ls, ps and id all now take
    a Z parameter than shows SELinux contexts.)
ls -lZ named.conf* -rw-r--r-- root named root:object_r:user_home_t named.conf -rw-r--r-- root root root:object_r:named_conf_t named.conf.orig
The file
    /etc/selinux/targeted/src/policy/domains/program/named.te
    contains the directive: (I had to install the
    selinux-policy-targeted-sources package to have the
    source.)
r_dir_file(named_t, named_conf_t)
This means that subjects of type named_t should be
    given read access to objects of type named_conf_t.
    Previously in the file there was the line:
can_exec(named_t, named_exec_t)
Which means that subjects of type named_t can
    execute objects of type named_exec_t.
    (/usr/sbin/named is of type
    named_exec_t.)
So, to fix my problem, I have to fix the context. The way to that is:
restorecon -v /var/named/chroot/etc/named.conf
The same problem exists for the new zone files, so I also have to do:
restorecon -v /var/named/chroot/var/named/*
In an attempt to reduce the number of problems that we are having with misconfigured machines, I set up a DHCP server. The setup is pretty straight forward. I got the mac address off of each machine set up some blocks:
192.168.99.0/26
      (192.168.99.0 - 192.168.99.63)192.168.99.64/26
      (192.168.99.64 - 192.168.99.127)192.168.99.192/26
        (192.168.99.192 - 192.168.99.254)
        192.168.99.254192.168.99.250192.168.99.251The basic file came from
    /usr/share/doc/dhcp-3.0.1/dhcpd.conf.sample and I
    edited it and put it at /etc/dhcpd.conf.
There is a SELinux problem here as well. There is a ownership
    problem like with named, but additionally, for the dnydns there is
    a shared file, /etc/rndc.key, with the authentication
    key used to update the server.
When I initially tried to run the program, I got an access denied error and in the logs it said:
audit(911596073.741:0): avc:  denied  { search } for pid=16624
   exe=/usr/sbin/dhcpd name=named dev=dm-0 ino=426311
   scontext=root:system_r:dhcpd_t tcontext=system_u:object_r:named_zone_t tclass=dir
    /etc/rndc.key is just a symlink to
    /var/named/chroot/etc/rndc.key. The directory is of
    type named_conf_t which by the default policy dhcpd
    can't access. There is probably a more graceful way to deal with
    this problem, but all I did was to grant it premission to the
    whole context: (as well as giving permission to read
    rndc.key of the same type)
cat >> /etc/selinux/targeted/src/policy/domains/program/dhcpd.te << EOF
# Added to allow shared key config with bind:
allow dhcpd_t named_conf_t:dir { search };
allow dhcpd_t named_zone_t:dir { search };
allow dhcpd_t named_conf_t:file { read getattr };
EOF
make -C /etc/selinux/targeted/src/policy/ load
    
    I've done the DNS and DHCP servers before. I've even done a domain controller and some LDAP programming. I've never had a Linux lab to run before, so this was my first time setting up a shared authentication source for Linux boxen. The majority of the information on the setup came from the Linux Documention Project.
The first issue was to get the server up and running. This took
    an edit of /etc/openldap/slapd.conf to set
    the suffix, rootdn and
    rootpw. Also I tighetened the default security policy
    which is nonexistent and enabled TLS.
The default security policy gives everyone read access to
    everything, which is something of a problem. It also restricts
    write access only to the server administrator which means no users
    can change their passwords. So the security changes in slapd.conf have to
    be put into place before the setup will work.
Also, the migration will put the entries into an organizational
    unit, People under the base dn and groups under
    Group. Once the server is started you have to create
    those base entries. If
    necessary, you can clear the directory first using
    ldapdelete or just removing all the data files in
    /var/lib/ldap/.
service ldap stop
rm -rfv /var/lib/ldap/*
service ldap start
admin=$(grep -e ^rootdn /etc/openldap/slapd.conf | \
        sed -e "s/^rootdn[[:space:]]\+\"\([^\"]\+\)\"/\\1/")
ldapadd -H ldaps://localhost -D "$admin" -xW -f base.ldif
    To migrate the existing information over to LDAP uses some perl scripts incuded in the
    distribution. Some setup is required by setting the environment
    variable LDAP_BASEDN before running:
export LDAP_BASEDN="o=Académie Cisco,o=Université de Nouakchott,c=MR" /usr/share/openldap/migration/migrate_passwd.pl /etc/passwd > passwd.ldif ldapadd -H ldap://localhost -D "$admin" -xW -f passwd.ldif /usr/share/openldap/migration/migrate_group.pl /etc/group > group.ldif ldapadd -H ldap://localhost -D "$admin" -xW -f group.ldif
This firewall will not actually be authenticating against the
    LDAP server, so the other changes are to the clients. I needed to
    update the configuration of the name service switch at
    /etc/nsswitch.conf,
    the PAM config at /etc/pam.d/system-auth and
    the default LDAP config at /etc/ldap.conf.
    (system-auth and
    ldap.conf
    were primarily updated by authconfig.) Also, to unify
    things a bit, I removed /etc/openldap/ldap.conf and
    made that a symlink to /etc/ldap.conf. Nsswitch
    uses the file in etc and ldapsearch uses
    the one in openldap, but the format is the same.
The one important thing to note with using the same file for
    both /etc/ldap.conf and
    /etc/openldap/ldap.conf is that
    PAM does not respect the uri directive, and so if you
    used that it is also necessary to include a host
    entry.
The debugging of this step proved a little troublesome, some commands that I found useful:
To verify that the ldap server was running and that I could connect from the client:
ldapsearch -x -H ldaps://firewall "(uid=will)"
On the server, in order to know which connections were being made and how, I did:
slapd -u ldap -d 1 -h "ldap:/// ldaps:///"
The debug levels is a bitmask (so you add the values to combine them):
| Level | Effect | 
|---|---|
| -1 | enable all debugging | 
| 0 | no debugging | 
| 1 | trace function calls | 
| 2 | debug packet handling | 
| 4 | heavy trace debugging | 
| 8 | connection management | 
| 16 | print out packets sent and received | 
| 32 | search filter processing | 
| 64 | configuration file processing | 
| 128 | access control list processing | 
| 256 | stats log connections/operations/results | 
| 512 | stats log entries sent | 
| 1024 | print communication with shell backends | 
| 2048 | print entry parsing debugging | 
In the end I turned on all debugging and found that my problem
    was I had used both a ldaps:// uri and the ssl
    start_tls command in /etc/ldap.conf. It was
    trying to start TLS twice and was failing. After this was fixed I
    could do:
getent passwd
And it would return results both from /etc/passwd
    on the machine and from the LDAP server.
Also the passwd command now works correctly to
    change passwords. The one potential issue is I can't change a
    user's password without knowing their old password. The system has
    to bind the LDAP server with an account with the permission to
    change the password and only the user and rootdn have
    that right. What I would like is to have it use the
    rootdn to bind when I'm running as root. I can have
    it do that, but only if I store the password in
    /etc/ldap.secret and I don't want to do that on all
    the workstations. I'll have to deal with this later.
Though my lab is a salle of logiciel libre, the primary operating system currently installed is XP Pro with French and Arabic MUI. A nice setup even if it does come from the evil empire. Hopefully with this new Fedora setup I can get some people weaned.
The machines all have really restricted local user accounts that only let the students read and run a few basic programs. For the other teachers and myself though I want for them to be able to log in with a roaming profiles. Given that I hardly want to have to touch each computer to add accounts, I need a domain controller.
It just took making a few changes to the default
    /etc/samba/smb.conf.
Before I could use the tools included for managing the LDAP server, I had to install a perl LDAP module:
perl -MCPAN -e 'install ldap'
Or, actually for the server I was setting up I was having a problem with the OOM killer kicking in and killing off both the CPAN update and my ssh session, so I had to do the install by hand:
After the modules were installed, I updated the config file for the included ldap tools at /usr/share/doc/samba-3.0.8/LDAP/smbldap-tools/smbldap_conf.pm. Then I ran the script to create all the needed base entries:
perl /usr/share/doc/samba-3.0.8/LDAP/smbldap-tools/smbldap-populate.pl
Then I added a couple NT accounts just to try out that it was working:
smbpasswd -a root
To see if I could connect then I did:
smbclient //localhost/root -U root
Now I wanted to take hosts and join them to the domain controller. Each machine has to be added to the database to join the domain. To do this automatically, the domain controller needs access to some scripts. Rather than putting the actual paths in the config file, I made some symbolic links:
groupadd smbdomain mkdir -p /home/samba/netlogon