Skip to main content
Welcome guest. | Register | Login | Post

Publish Your Office Docs, Demo Linux, Impress the Boss

14 replies [Last post]
supermike's picture
Offline
Joined: 2006-02-17

PUBLISH YOUR OFFICE DOCS FAST AND DEMONSTRATE LINUX TO THE BOSS

Got an office environment where the boss, who uses Windows, says he wants an intranet website where you can publish some Word docs? Want to use Linux? Don't want to go to the extreme of Mambo, Drupal, or some other CMS system? Here's something I've whipped up. It involves using a Linux Samba share along with a PHP-based web server on that same system. For Word doc conversion, I used wvHTML from the wv toolset, but if you don't like its simplistic conversion, you can use something else or ask the boss to save in HTML from within Word itself. And for obvious reasons, hopefully the system is set up with a static IP address instead of DHCP. Note that this information here is more for intermediate Linux users, not for newbies.

1. You might not have the wv toolset. Many people do not in their default distro. I used apt to go get it. In Ubuntu, I turned on Universe, Multiverse, and Backports, apt-get update, and then apt-get install wv. I then commented out Universe, Multiverse, and Backports, followed by apt-get update, again. You can also get it off of http://freshmeat.net.

2. Create a Samba share on your Linux distro so that the boss can upload his docs. In my case with Ubuntu Linux, I just created a folder, rightclicked it and chose Share Folder, filled out the Samba form, and made it a hidden share (turned off Browse This Folder option) because I don't want to announce to my network that I'm running a Samba server. I then created a local account for him to use to reach my system.

3. If you have a firewall, your iptable exceptions rules more than likely will be, among your other rules:

iptables -A INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 138 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 139 --syn -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 445 --syn -j ACCEPT

4. Create a symbolic link from your website directory to this shared folder directory.

5. Drop these pages into that directory:

--save as index.php--

<?php
	$sFiles = `ls -1 | grep -i ".html\|.htm" | sort`;
	$aFiles = explode("\n",$sFiles);
	foreach ($aFiles as $s1) {
		$s2 = str_replace('.html','',$s1);
		$s2 = str_replace('.htm','',$s2);
		$s2 = str_replace('_',' ',$s2);
		$s2 = strtolower($s2);
		$s2 = ucwords($s2);
		// next 2 are optional
		$s2 = str_replace('Pc ','PC ',$s2); //for PC instead of Pc
		$s2 = str_replace(' V',' v',$s2); //for little v for version
		// end optional
		$s1 = str_replace(' ','%20',$s1);
		$sBuild .= "<a href='$s1'>$s2</a><BR>\n";
	}
	$sTitle = 'YOUR TITLE HERE';
?>
<!doctype public "-//w3c//dtd html 4.01 transitional//en" 
		"http://www.w3.org/TR/html4/loose.dtd"">
<HTML>
<HEAD><TITLE><?= $sTitle ?></TITLE>
</HEAD>
<BODY bgcolor=white marginwidth=0 marginheight=0 topmargin="0" leftmargin="0" >
<table border=0><tr><td></td></tr></table>
<BLOCKQUOTE>
<P><h1><a style="text-decoration: none;color: black" href="regen1.php"><?= $sTitle ?></a></h1></P>
<BLOCKQUOTE>
<?= $sBuild ?>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BODY>
</HTML>

--end index.php--

--save as regen1.php--

<!doctype public "-//w3c//dtd html 4.01 transitional//en" 
		"http://www.w3.org/TR/html4/loose.dtd"">
<html>
<head>
<title>Regenerating...</title>
<META HTTP-EQUIV="REFRESH" CONTENT="1;regen2.php">
</head>
<body>
<h3>Regenerating HTML from Word Docs...</h3>
</body>
</html>

--end regen1.php--

--save as regen2.php--

<?php

	function Redirect($whereto) {
		$whereto = trim($whereto);
		if ($whereto != '') {
			header('Location: ' . $whereto);
			exit;
		}
	}

	`
		for f in *.doc
		do
			a=\$(echo -en "\$f" | sed "s/.doc/.html/g")
			wvHtml "\$f" "\$a"
		done
	`;
	
	Redirect('index.php');
?>

--end regen2.php--

6. Now, for the rest, you might want to play with file and directory security, and you might have trouble with Samba authentication, so you may have to read about those on the web.

7. Now tell your boss or coworkers to upload the docs to this hidden share by doing something like Start, Run, \\<your IP address>\<your hidden share name>$ and logging in to see it.

8. They can hit the website by going to its web URL, which it might be, depending on how you set this up, as http://<your IP address>/docs/index.php

9. When the boss drops new docs in this directory, he needs to hit the URL and click on the title, which is cleverly disguised as a hidden link that runs a script to regenerate the HTML.

10. Don't like the way the HTML is formatted? You can either replace the wv toolset with something better if you can find it, ask the boss to save as HTML in the first place, or learn how to make Word docs that run through this filter very neatly. For the former two of those options, obviously, you're going to want to edit the PHP a little to set that up.

11. She ain't pretty, but that's nothing that a little CSS can't fix. Eye At least she's functional.

Hope this helps you get this up and running fast!

supermike's picture
Offline
Joined: 2006-02-17

Libervisco or moderator -- can you fix the "http://<your" above for me? I don't know how to turn that off so that it doesn't make it a real hyperlink. To wrap with code tags makes it look funny.

Offline
Joined: 2006-03-28

I'd open the SMB-ports like that:

iptables -A INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 138 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 139 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 445 -j ACCEPT

You also test for SYN won't allow the whole conversation but only the connection.
Therefor you'd need connection-tracking if you want to use it the way you poste.
Something like this should do:

iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

If you like you can also add protocol and port there, but since this just handles connections which are allowed by other rules there should be no need for this.

libervisco's picture
Offline
Joined: 2006-05-04

Great work again supermike! Is this again a publishable article? Let me know.

"supermike" wrote:

Libervisco or moderator -- can you fix the "http://<your" above for me? I don't know how to turn that off so that it doesn't make it a real hyperlink. To wrap with code tags makes it look funny.

I think wrapping in code tags is pretty much the only way to do that. Hmm.. yet another of those tiny features that would be cool, to allow turning off automatic link detection...

I'll see if I can find a way to do that..

Thanks

supermike's picture
Offline
Joined: 2006-02-17

reptiler: So you say drop the --syn and add in the state established thing. Can you demonstrate (and perhaps test) for me how this would fit into a script that sort of looks like the following?

iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport XXX --syn -j ACCEPT
iptables -A INPUT -p udp -m udp --dport XXX -j ACCEPT
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ1 --sport 53 -d 0/0 -j ACCEPT
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ2 --sport 53 -d 0/0 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --syn -j REJECT
iptables -A INPUT -p udp -m udp -j REJECT
iptables -L

notes:
Replace XXX with port nums and eliminate cases where you don't need syn and/or one of the protocols (tcp,udp). Also use sport if dport doesn't work. The ZZ stuff is for the primary and second DNS from /etc/resolv.conf.

libervis: Pretty much publishable if I can get with reptiler to iron this last bit out. I also found the workaround for describing fill-in-the-blank kinds of URLs. I found I can use something like http:&#47;&#47;test which comes to http://test.

libervisco's picture
Offline
Joined: 2006-05-04
"supermike" wrote:

libervis: Pretty much publishable if I can get with reptiler to iron this last bit out.

Sure, no problem.

"supermike" wrote:

I also found the workaround for describing fill-in-the-blank kinds of URLs. I found I can use something like http://test which comes to http://test.

That's awesome. Now I know too. Smiling

Thanks alot!

a thing's picture
Offline
Joined: 2005-12-20

Anything for ODTs?

supermike's picture
Offline
Joined: 2006-02-17

a_thing: he he. Do you have this book of obscure acronyms? I think this is the second time I have had to look up your stuff at a site like:

http://acronyms.thefreedictionary.com/ODT

I'm still scratching my head on what that means. Or die trying? Smiling

tbuitenh's picture
Offline
Joined: 2005-12-21

Open Document Text Eye

supermike's picture
Offline
Joined: 2006-02-17

I hope reptiler replies soon. I'd like to wrap up this doc this weekend.

Offline
Joined: 2006-03-28

Don't worry.
I'm still busy compiling everything. KDE's nearly finished...

Well, here we go...
Quite some time ago I worked out some more or less flexible script I use to bring up the rules.
Since ppp0 is my connection to the rest of the world, and propably for 90% of the people out there I didn't change that.
In case it's just a server in a LAN eth0 or anything else were packets come in also works.

case "$1" in
    start)
	$0 enablefirewall
	;;
    stop)
	$0 disablefirewall
	iptables -F
	iptables -X
	;;
    enablefirewall)
    	echo "Enabling Firewall"
	iptables -N firewall
	iptables -A firewall -m state --state INVALID -j DROP
	iptables -A firewall -m state --state ESTABLISHED,RELATED -j ACCEPT
	iptables -A firewall -m state --state NEW -i ! ppp0 -j ACCEPT
	iptables -A firewall -p tcp -j REJECT --reject-with tcp-reset
	iptables -A firewall -j DROP
	iptables -A INPUT -j firewall
	iptables -A FORWARD -j firewall
    	;;
    disablefirewall)
    	echo "Disabling Firewall"
	iptables -D INPUT -j firewall
	iptables -F firewall
	iptables -X firewall
    	;;
    restart)
	$0 stop  &&  $0 start  ||  return=$rc_failed
	;;
    *)
	echo "Usage: $0 {start|stop||restart|enablefirewall|disablefirewall}"
	exit 1
	;;
esac

Okay, some words about that.
enablefirewall sets up the chain firewall, which goes to the end of INPUT. This should always be at the end of INPUT because nothing will ever come out of that chain again.

	iptables -A firewall -p tcp -j REJECT --reject-with tcp-reset
	iptables -A firewall -j REJECT

TCP-packets are rejected with a TCP-reset. A port-scanner will mark this port as closed, not as filtered like when the packed is dropped.
Everything else get's rejected. Since this usually is UDP (most people anyway just use TCP, UDP and ICMP) the standard reject is okay here. This sends icmp-port-unreachable, which, at least for UDP, also causes the port-scanner to think it's closed and not filtered. Anyway UDP doesn't have real connection like TCP which makes determining the state of a UDP-port quite a game. But since this is not about port-scanning I don't want to elaborate further on this.
The following lines set up connection tracking.

	iptables -A firewall -m state --state INVALID -j DROP
	iptables -A firewall -m state --state ESTABLISHED,RELATED -j ACCEPT
	iptables -A firewall -m state --state NEW -i ! ppp0 -j ACCEPT

Although UDP doesn't use connections NetFilter can even handle UDP properly.
The first line drops everything which is invalid, whatever this may mean exactly. But since nobody wants invalid packages we can drop this. Never had a bad experience with that.
The second line is for all connections which all already established, and connections related to these, like on FTP which uses 2 connections.
This enables all traffic we requested to come back in. Meaning we have full access to the outside world. And since the 2 lines shown before reject everything which doesn't fit these rules nothing comes in, except for the stuff we requested to get.
The third line enables us to establish new connections. Or following the command it accepts only new connections which do not come in from ppp0. Meaning all connections coming in and going out on lo, eth0, etc. and all connections going out on ppp0, but no connections coming in on ppp0. A nice side-effect of this is that it also enables loopback-traffic, which sometimes is necessary for some services.
Now we want to get some holes into this. Let's say we want to give the world access to our cool website, so we have to open up TCP-ports 80 and 443 (or wherever you have your Apache running).
Since this script already offers a good base to make it modular we want to keep it that way and add a little "module" for HTTP- and HTTPS-access.
This code will do the trick

    enablehttp)
    	echo "Enabling HTTP-access"
	iptables -N http
	iptables -A http -p tcp --dport 80 -m state --state INVALID -j DROP
	iptables -A http -p tcp --dport 443 -m state --state INVALID -j DROP
	iptables -A http -p tcp --dport 80 -j ACCEPT
	iptables -A http -p tcp --dport 443 -j ACCEPT
	iptables -I INPUT 1 -j http
    	;;
    disablehttp)
    	echo "Disabling HTTP-access"
	iptables -D INPUT -j http
    	;;

Okay, last line comes first...

	iptables -I INPUT 1 -j http

This inserts the chain http as the first chain in INPUT. This is important because that way packages go through http before firewall which is necessary because nothing ever comes back out of firewall, as I explained before.
But since this chain is handled before we drop all the invalid packages we drop all invalid packages to our HTTP-ports.

	iptables -A http -p tcp --dport 80 -m state --state INVALID -j DROP
	iptables -A http -p tcp --dport 443 -m state --state INVALID -j DROP

And finally open them for free access:

	iptables -A http -p tcp --dport 80 -j ACCEPT
	iptables -A http -p tcp --dport 443 -j ACCEPT

To have it started and stopped with start and stop we modify these like shown here:

    start)
	$0 enablefirewall
	$0 enablehttp
	;;
    stop)
	$0 disablehttp
	$0 disablefirewall
	iptables -F
	iptables -X
	;;

I think this should do for now. If you still have some questions about this just let me know.

[Edit] Damn it, that's got longer than I expected...

supermike's picture
Offline
Joined: 2006-02-17

reptiler:

I guess it comes down to needing a more specific answer to the Samba situation. Here's the question again:

So you say drop the --syn and add in the state established thing.

Can you demonstrate (and perhaps test) for me how this would fit into a script that sort of looks like the following?

iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport XXX --syn -j ACCEPT
iptables -A INPUT -p udp -m udp --dport XXX -j ACCEPT
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ1 --sport 53 -d 0/0 -j ACCEPT
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ2 --sport 53 -d 0/0 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --syn -j REJECT
iptables -A INPUT -p udp -m udp -j REJECT
iptables -L

notes:
Replace XXX with port nums and eliminate cases where you don't need syn and/or one of the protocols (tcp,udp). Also use sport if dport doesn't work. The ZZ stuff is for the primary and second DNS from /etc/resolv.conf.

Offline
Joined: 2006-03-28

Okay, I just did a little test and only using the --syn-rules does not work.
When I try to access the Linux-box via SMB I get an error saying the box is not accessible.

Adding the following line is enough:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Your script therefore would look like that:

iptables -F 
iptables -A INPUT -i lo -j ACCEPT 
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 139 --syn -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 445 --syn -j ACCEPT 
iptables -A INPUT -p udp -m udp --dport 137 -j ACCEPT 
iptables -A INPUT -p udp -m udp --dport 138 -j ACCEPT 
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ1 --sport 53 -d 0/0 -j ACCEPT 
iptables -A INPUT -p udp -m udp -s ZZ.ZZ.ZZ.ZZ2 --sport 53 -d 0/0 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --syn -j REJECT 
iptables -A INPUT -p udp -m udp -j REJECT 
iptables -L

Your lines

iptables -A INPUT -p tcp -m tcp --dport 139 --syn -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 445 --syn -j ACCEPT 

just allow the first package of the connection-attempt since here all flags are checked and only syn is allowed.
If I remember correctly the 3-way-handshake looks like this
SYN - SYN/ACK - ACK
So you receive SYN, send back SYN/ACK and never receive ACK because the rules just allow SYN.

supermike's picture
Offline
Joined: 2006-02-17

reptiler: I've updated my two "pinned" firewall docs (one long, one short) with your advice after I tested it and found that it works.

libervisco: As for the original doc, it's ready for publishing. The holes that I mention for Samba still stand. The statement:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

...is something that users are recommended to put in their standard firewall script, anyway, and I had left it out. I've updated those other two pinned firewall docs with that statement, so this should not affect this doc here. Ready to expose it and pin it?

libervisco's picture
Offline
Joined: 2006-05-04