diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index a0ec518172a03415338f9134a57d69c564a7780d..b7cd11d19ff47f1a71de551d49abc32d35784962 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -232,6 +232,11 @@ public class Router {
         buf.append("</select>");
         buf.append("</form>");
 
+        buf.append("<form action=\"/shutdown\" method=\"GET\">");
+        buf.append("<b>Shut down the router:</b>");
+        buf.append("<input type=\"password\" name=\"password\" size=\"8\" />");
+        buf.append("<input type=\"submit\" value=\"shutdown!\" />");
+        buf.append("</form>");
         buf.append("<hr />\n");
 
         if ( (_routerInfo != null) && (_routerInfo.getIdentity() != null) )
diff --git a/router/java/src/net/i2p/router/admin/AdminRunner.java b/router/java/src/net/i2p/router/admin/AdminRunner.java
index c01b52bb3b4007b6b9c50ca7368be14c75e86e2e..6a9dbc607b3acf3f1c10435cfa0e7d90a24737a6 100644
--- a/router/java/src/net/i2p/router/admin/AdminRunner.java
+++ b/router/java/src/net/i2p/router/admin/AdminRunner.java
@@ -15,6 +15,7 @@ import java.util.Set;
 import net.i2p.data.Hash;
 import net.i2p.router.RouterContext;
 import net.i2p.util.Log;
+import net.i2p.util.I2PThread;
 
 class AdminRunner implements Runnable {
     private Log _log;
@@ -52,6 +53,8 @@ class AdminRunner implements Runnable {
         } else if (command.indexOf("setTime") >= 0) {
             setTime(command);
             reply(out, "<html><body>Time updated</body></html>");
+        } else if (command.indexOf("/shutdown") >= 0) {
+            reply(out, shutdown(command));
         } else if (true || command.indexOf("routerConsole.html") > 0) {
             reply(out, _context.router().renderStatusHTML());
         }
@@ -135,4 +138,28 @@ class AdminRunner implements Runnable {
     private void setTime(long now) {
         _context.clock().setNow(now);
     }
+    
+    
+    private static final String SHUTDOWN_PASSWORD_PROP = "router.shutdownPassword";
+    private String shutdown(String cmd) {
+        String password = _context.router().getConfigSetting(SHUTDOWN_PASSWORD_PROP);
+        if (password == null)
+            password = _context.getProperty(SHUTDOWN_PASSWORD_PROP);
+        if (password == null) 
+            return "No shutdown password specified in the config or context - <b>REFUSING SHUTDOWN</b>." +
+                   "<a href=\"/routerConsole.html\">back</a>";
+        if (cmd.indexOf(password) > 0) {
+            I2PThread t = new I2PThread(new Runnable() {
+                public void run() { 
+                    try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
+                    _context.router().shutdown();
+                }
+            });
+            t.start();
+            return "Shutdown request accepted.  Killing the router in 30 seconds";
+        } else {
+            return "Incorrect shutdown password specified.  Please edit your router.config appropriately." +
+                   "<a href=\"/routerConsole.html\">back</a>";
+        }
+    }
 }