Publish Your Office Docs, Demo Linux, Impress the Boss
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.
At least she's functional.
Hope this helps you get this up and running fast!










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'd open the SMB-ports like that:
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:
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.
Great work again supermike! Is this again a publishable article? Let me know.
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
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://test which comes to http://test.
libervis: Pretty much publishable if I can get with reptiler to iron this last bit out.
Sure, no problem.
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.
Thanks alot!
Anything for ODTs?
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?
Open Document Text
I hope reptiler replies soon. I'd like to wrap up this doc this weekend.
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 ;; esacOkay, 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.
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.
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...
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.
And finally open them for free access:
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...
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.
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:
Your script therefore would look like that:
Your lines
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.
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?
Supermike: Sure, if it's ready it can be moved to articles and put on homepage right away.
Thanks