Code Monkey home page Code Monkey logo

mirrorbits's Introduction

Build Status Go Report Card

Mirrorbits

Mirrorbits is a geographical download redirector written in Go for distributing files efficiently across a set of mirrors. It offers a simple and economic way to create a Content Delivery Network layer using a pure software stack. It is primarily designed for the distribution of large-scale Open-Source projects with a lot of traffic.

mirrorbits_screenshot

Main Features

  • Blazing fast, can reach 8K QPS on a single laptop
  • Easy to deploy and maintain, everything is packed in a single binary
  • Automatic synchronization with the mirrors over rsync or FTP
  • Response can be either JSON or HTTP redirect
  • Support partial repositories
  • Complete checksum / size control
  • Realtime monitoring and reports
  • Disable misbehaving mirrors without human intervention
  • Realtime decision making based on location, AS number and defined rules
  • Smart load-balancing over multiple mirrors in the same area to avoid hotspots
  • Ability to adjust the weight of each mirror
  • Limit access to a country, region or ASN for any mirror
  • Clustering (multiple mirrorbits instances)
  • High-availability using redis-sentinel
  • Automatically fix timezone offsets for broken mirrors
  • Realtime statistics per file / mirror / date
  • Realtime reconfiguration
  • Seamless binary upgrade (aka zero downtime upgrade)
  • Mirmon support
  • Full IPv6 support
  • If-Modified-Since (RFC-7232) support
  • more...

Is it production ready?

Yes! Mirrorbits has served billions of files already and is known to be running in production at:

Yet some things might change before the 1.0 release. If you intend to deploy Mirrorbits in a production system it is advised to notify the author first so we can help you to make any transition as seamless as possible!

Previous projects which have used Mirrorbits:

Quick start

Prerequisites

  • Go 1.11 or later
  • Protobuf (protoc)
  • Redis 3.2 or later (with persistence enabled)
  • GeoIP2 databases from Maxmind (preferably updated regularly)

⚠️ GeoIP-legacy is not supported anymore, please use the new GeoIP2 mmdb databases!

Optional:

  • redis-sentinel (for high-availability support)

Upgrading

Before upgrading to the latest version, please check this guide.

Installation

You can either get a prebuilt version or choose to build it yourself.

Docker

A docker "quick start" can be found on the wiki.

Manual build

Go >= 1.11:

$ git clone https://github.com/etix/mirrorbits.git
$ cd mirrorbits
$ sudo make install

Go < 1.11:

$ go get -u github.com/etix/mirrorbits
$ cd $GOPATH/src/github.com/etix/mirrorbits
$ sudo make install

The resulting executable should now live in your /usr/local/bin directory. You can also specify a PREFIX or DESTDIR if necessary:

sudo make install PREFIX=/usr

Configuration

A sample configuration file can be found here.

Running

Mirrorbits is a self-contained application and can act, at the same time, as the server and the cli.

To run the server:

mirrorbits daemon

Additional options can be found with mirrorbits -help.

To run the cli:

mirrorbits help

Add a mirror:

mirrorbits add -ftp="ftp://ftp.mirrors.example/myproject/" -http="http://ftp.mirrors.example/myproject/" mirrors.example

Enable the mirror:

mirrorbits enable mirrors.example

Realtime file availability

By appending ?mirrorlist to any file served by mirrorbits, you'll be able to get some useful realtime informations about the given file. You can see a live example here.

Realtime mirrors statistics

Mirror statistics are available by querying mirrorbits with the ?mirrorstats argument. You can see a live example here.

Clustering / High availability

Multiple instances of mirrorbits can be started simultaneously on different servers, discovery of other nodes should be automatic as long as all the instances are connected to the same redis server. In addition to the clustering it is advised to use redis-sentinel to monitor the database and gracefully handle failover.

Upgrading

Mirrorbits has a mode called seamless binary upgrade to upgrade the server executable at runtime without service disruption. Once the binary has been replaced on the filesystem just issue the following command in the cli:

mirrorbits upgrade

Considerations

  • When configured in redirect mode, Mirrorbits can easily serve client requests directly but it is usually recommended to set it behind a reverse proxy like nginx. In this case take care to pass the IP address of the client within a X-Forwarded-For header:
proxy_set_header X-Forwarded-For $remote_addr;
  • It is advised to never cache requests intended for Mirrorbits since each request is supposed to be unique, caching the result might have unexpected consequences.

We're social!

The best place to discuss about mirrorbits is to join the #VideoLAN IRC channel on Libera.chat. For the latest news, you can follow @mirrorbits on Twitter.

License MIT

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mirrorbits's People

Contributors

christophermluna avatar dbnicholson avatar elboulangero avatar etix avatar exec64 avatar fauust avatar florolf avatar infertux avatar julien-duponchelle avatar kib avatar lemeurherve avatar loanfedora avatar ott avatar palinurosec avatar poempelfox avatar rechi avatar samnazarko avatar thenameisnigel-old avatar wjt avatar wsnipex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mirrorbits's Issues

Improve web pages

The current implementation of the web pages is not good enough and since I'm not a web guy, any help on this side would be greatly appreciated.

http scan

Hi, we are migrating the parrotsec.org redirector to mirrorbits and i'm pretty new to this software.
is there any way to scan a mirror without rsync or ftp?

our previous mirror redirector (mirrorbrain) allowed http repositories to be easily (but slowly) scanned via http if no rsync/ftp url was provided

Crash when no fallbacks are specified in config

There seems to be a missing nil check in http.go#243 that causes it to deref a nil variable when there's no fallbacks specified in the config file..

2015/07/29 09:48:38 http: panic serving 127.0.0.1:33857: runtime error: invalid memory address or nil pointer dereference
goroutine 2782 [running]:
net/http.func·011()
        /usr/local/go/src/pkg/net/http/server.go:1100 +0xb7
runtime.panic(0x7f2960, 0xc84db3)
        /usr/local/go/src/pkg/runtime/panic.c:248 +0x18d
main.(*HTTP).mirrorHandler(0xc20802a540, 0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410, 0xc2087558c0)
        /home/mirrorbits/gocode/src/github.com/etix/mirrorbits/http.go:243 +0x1034
main.(*HTTP).requestDispatcher(0xc20802a540, 0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /home/mirrorbits/gocode/src/github.com/etix/mirrorbits/http.go:188 +0x130
main.*HTTP.(main.requestDispatcher)·fm(0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /home/mirrorbits/gocode/src/github.com/etix/mirrorbits/http.go:78 +0x44
main.func·003(0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /home/mirrorbits/gocode/src/github.com/etix/mirrorbits/gzip.go:33 +0x2ec
net/http.HandlerFunc.ServeHTTP(0xc2080f8db0, 0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /usr/local/go/src/pkg/net/http/server.go:1235 +0x40
net/http.(*ServeMux).ServeHTTP(0xc208026b70, 0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /usr/local/go/src/pkg/net/http/server.go:1511 +0x1a3
net/http.serverHandler.ServeHTTP(0xc2080f2420, 0x7fcdd7478288, 0xc2086b1e00, 0xc20816e410)
        /usr/local/go/src/pkg/net/http/server.go:1673 +0x19f
net/http.(*conn).serve(0xc208218280)
        /usr/local/go/src/pkg/net/http/server.go:1174 +0xa7e
created by net/http.(*Server).Serve
        /usr/local/go/src/pkg/net/http/server.go:1721 +0x313

Add support for Github as download source

Hey!

My builds are automatically pushed to GH Releases.
Is it possible to use GH as a primary source for mirroring?
Will Mirrorbits pick downloads up and sync them to mirrors automatically?

Best, Jens

JS based secure downloader for non-HTTPS mirrors

This ticket come after few days of conversations around the security of VLC download procedures, starting from an HTTP clear-text website www.videolan.org along with get.videolan.org that could, and hopefully will, be upgrade to HTTPS-only with HSTS.

One of the claim of the team of VLC for not upgrading to HTTPS-only their website www.videolan.org and get.videolan.org (running mirrorbits) is that their mirrors are anyhow also HTTP-cleartext.

Aside that there are 35 out 88 mirrors already with HTTPS, this ticket is to propose a different approach to keep the "root of trust" on secured HTTPS-only version of videolan.org/get.videolan.org while keeping the mirrors also in HTTP in clear.

The idea is to make a small Javascript widget, using HTML5 Download API, that would be safely loaded from https://get.videolan.org when clicking download and will:

  • download using XMLHTTPRequest the binary of the installation as a JS blob
  • will automatically verify the signature from an HTTPS-only preloaded list of file hashes
  • if the signature will match, will trigger the browser download from a data:URI (with a similar approach to http://danml.com/download.html)

That way the root of trust, that today is broken because of missing HTTPS-only website, can stay there regardless of the security of the mirrors, the-facto preventing MITM attacks also without having to deploy the strict HTTPS+HSTS across all of the mirrors (but only on the main videolan.org domain sites).

Make special pages available on a custom path

We need something like what has been done on #31 to specify the endpoint in the configuration file instead of relying only on query arguments. The only legitimate use of the query arguments would be ?mirrorlist and ?stats (and thus remove ?mirrorstats and ?downloadstats).

Multiple instances on same host?

I've been wondering whether it's possible to run multiple instances of mirrorbits (meaning: for different projects, with a different set of mirrors) on the same host.
As you can use multiple config files and the config does allow you to set RedisDB which then seems to select a different DB, this should probably work?
However, the instances then still detect each other on startup: 2018/01/28 11:04:07.140 CET -> Node mirrorbits-21868 joined the cluster
As far as I understood the code, this is because it does some broadcast communication through the database, and that just uses the static string "HELLO" as a marker.
My attempt to fix this was to add the RedisDB-number to the string like that:

--- a/daemon/cluster.go
+++ b/daemon/cluster.go
@@ -11,6 +11,7 @@ import (
        "sync"
        "time"

+       . "github.com/etix/mirrorbits/config"
        "github.com/etix/mirrorbits/database"
        "github.com/etix/mirrorbits/mirrors"
        "github.com/etix/mirrorbits/utils"
@@ -94,6 +95,7 @@ func (c *cluster) Stop() {
 func (c *cluster) clusterLoop() {
        clusterChan := make(chan string, 10)
        announceTicker := time.NewTicker(1 * time.Second)
+       clusterAnnWithId := clusterAnnounce+fmt.Sprintf("%d", GetConfig().RedisDB)

        c.refreshNodeList(c.nodeID, c.nodeID)
        c.redis.Pubsub.SubscribeEvent(database.CLUSTER, clusterChan)
@@ -106,18 +108,18 @@ func (c *cluster) clusterLoop() {
                case <-announceTicker.C:
                        c.announce()
                case data := <-clusterChan:
-                       if !strings.HasPrefix(data, clusterAnnounce+" ") {
+                       if !strings.HasPrefix(data, clusterAnnWithId+" ") {
                                // Garbage
                                continue
                        }
-                       c.refreshNodeList(data[len(clusterAnnounce)+1:], c.nodeID)
+                       c.refreshNodeList(data[len(clusterAnnWithId)+1:], c.nodeID)
                }
        }
 }

 func (c *cluster) announce() {
        r := c.redis.Get()
-       database.Publish(r, database.CLUSTER, fmt.Sprintf("%s %s", clusterAnnounce, c.nodeID))
+       database.Publish(r, database.CLUSTER, fmt.Sprintf("%s%d %s", clusterAnnounce, GetConfig().RedisDB, c.nodeID))
        r.Close()
 }

That seems to work, the instances no longer see each other. Is that really all that's needed, or am I overlooking something here that will cause problems down the road?

Connect to specific redis database index

Hi :)

I'm wanting to use mirrorbits on a machine that already runs redis. So the database "0" is already in use. In mirrorbits.conf I can see:

RedisAddress: 127.0.0.1:6379
RedisPassword:

but I don't see a parameter to connect to another database than DB 0;

Is there a way to change the database index used by mirrorbits?

Raphaël

Add Metalink (v4) support

Metalink support would enable traffic distribution, integrity check (file checksum) and nice download resume (most meta4 aware download clients track download progress and can resume download in any point). Optional fragment checksum feature would enable re-downloading only broken parts. New ?meta4 endpoint would contain data from ?mirrorlist and ?sha1/md5, could also contain file size (that currently can be obtained only from Content-Length header) so it would help allocate disk space before downloading.

scan mirror before enabling after down/unreachable

I think it would be wise to scan a mirror that was "unreachable" before mirrorbits auto enables it.

For instance

Mirror goes down,

mirrorbits sees this and disables it.

While mirror is down, some directory's are removed.

mirror back up, mirrorbits blindly enables mirror assuming it has all the files it did when it went down.

users get a 404 for missing files.

Maybe there's a timer where it will do this automatically.

Keep up the good work : ]

feature: show global stats (mirrors combines) and add weekly/monthly/yearly per mirror

As title says. Currently data usage in mirrorstats is onnly shown per mirror when you hover over it. However it's only current day total so to actually know the full day usage you would have to check at specific time.
If possible a counter for current day / month / year would help doing estimations of traffic (same as done for download counts).
As extra a global counter for all mirrors combined would be a nice extra

@kib will probably already see what's available and adjust the layout

Some downloads showing "Service Unavailable"

Hi,

We're using mirrorbits for lineageos (https://download.lineageos.org / https://mirrorbits.lineageos.org). I'm running into a problem where artifacts occasionally show "Service Unavailable", even when they're on disk. The problem goes away when mirrorbits is restarted. There's nothing applicable in the log file.

Last example (we've since restarted so its available again): https://mirrorbits.lineageos.org/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip

And, redis information for that file:

127.0.0.1:6379> KEYS *lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "FILEINFO_ftp.tugraz.at_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
2) "FILEINFO_main_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
3) "FILEINFO_acc.umu.se_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
4) "FILEINFO_mirror.karneval.cz_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
5) "FILEMIRRORS_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
6) "FILE_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"
7) "FILEINFO_mirror.brauser.io_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip"

127.0.0.1:6379> HGETALL FILEINFO_ftp.tugraz.at_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "size"
2) "525981555"
127.0.0.1:6379> HGETALL FILEINFO_main_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "size"
2) "525981555"
127.0.0.1:6379> HGETALL FILEINFO_acc.umu.se_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "size"
2) "525981555"
127.0.0.1:6379> HGETALL FILEINFO_mirror.karneval.cz_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "size"
2) "525981555"
127.0.0.1:6379> HGETALL FILEMIRRORS_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> SMEMBERS FILEMIRRORS_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "mirror.karneval.cz"
2) "mirror.brauser.io"
3) "main"
4) "ftp.tugraz.at"
5) "acc.umu.se"
127.0.0.1:6379> HGETALL FILEINFO_mirror.brauser.io_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
1) "size"
2) "525981555"
127.0.0.1:6379> HGETALL FILE_/full/kiwi/20170125/lineage-14.1-20170125-nightly-kiwi-signed.zip
 1) "size"
 2) "525981555"
 3) "modTime"
 4) "2017-01-25 07:24:10 +0000 UTC"
 5) "sha1"
 6) "71fe164924d74b02a7fec80e90f70dca23c3e7af"
 7) "sha256"
 8) ""
 9) "md5"
10) ""

Any ideas on how I can track down what's causing this? Thank you!

Creating customised JSON download page

I plan on evaluating mirrorbits over the next week or so before we potentially swap out mirrorbrain. One of the key features that attracts us to mirrorbits is the customized download page feature:

"mirrorbits also has a JSON query API to be able to generate your own customized download page for showing alternate mirrors or a sponsor logo along with a countdown"

This is something we had planned on trying to put together on mirrorbrain for sometime but never got round to it. Is there any documentation / sample pages on how to do this? I had a quick look in the repo but couldn't see anything obvious....

thanks

Make it possible to exclude some files / always send them to fallback

We are hosting an APT repository with pdiffs, and I noticed Mirrorbit's scan feature uses file sizes to check file integrity.

The Index file on an APT repository may not change in size when it is updated.

If you look at http://realtime.mirror.osmc.tv//osmc/apt/dists/jessie-devel/main/binary-armhf/Packages.diff/Index, you will see that the current checksum is stored as are a few previous ones. But this file never grows in size as checksums are simply replaced. This can give a 'Hash Sum Mismatch' error when running apt-get update.

It would be great if we could use a fallback specified in the mirrorbits.conf for certain paths or filenames.

Fill local repository from upstream within mirrorbits

Hi,

It would be awesome if mirrorbits has support for automatic 'cron-like' syncing of another mirror to the local repository, so that practiclty the first step in the quick start can be replaced with a mirrorbits feature.

I would like to have this because if you currently have to maintain a (software/Linux Distro)mirror, you need to maintain a bunch of scripts and cron's to keep it up-to-date with the official ones.
It would make my life a lot easier when I'm able to just do something like

mirrorbits add -http http://[official_mirror_x] -rsync rsync://[official_mirror_x] mirror_x
mirrorbits pull mirrox_x
mirrorbits scan -enable mirror_x
mirrorbits update

And were 'pull' starts to sync the mirrors content over http/rsync to the local repository.
After which you can use the local repository as the preferred one for serving requests, and in case of an local error redirect/proxy users to another working one.

If I go over this quickly, this means that their will need to be some sort of another mode in mirrorbits in the first place which allows it to serve requests from it's local repository if preferred right?

Is this something you guys would be interested in adding?

Cannot use mirrorbits edit if hash computation is disabled

When one disables all hashing algorithms in the config because they are just not interested in mirrorbits computing them for all files, it becomes impossible to use "mirrorbits edit" to edit mirror settings. The reason is that

chk2, _ := filesystem.HashFile(f.Name())
uses filesystem.HashFile() to determine if the temporary file has been modified, and that check always returns true if there are no hashing algorithms enabled.
I think it should still be possible to edit your config even if you do not want to waste CPU and I/O cycles with mirrorbits hashing all files...

Impossible to edit mirror when name is subset of other mirror

When there are two mirrors with very similar names the show command will fuzzy logic list both mirrors, in my opinion this is a good thing.

The issue however is threefold:

  • The edit command will do the same, and does not use strict checking
  • There is no way (I found) to change the descriptive name of a mirror
  • (SOLVED) It is impossible to add a mirror with the same name as one that was previously removed.

Example:

First I add a few mirrors called test.example.com and secondtest.example.com

$ mirrorbits add -http="http://test.example.com" test.example.com 
Warning: unable to guess the geographic location of test.example.com
Mirror added successfull
$ mirrorbits add -http="http://secondtest.example.com" secondtest.example.com
Warning: unable to guess the geographic location of test.example.com
Mirror added successfull

It is clear this worked from the output of the show command

$ mirrorbits show example
secondtest.example.com
test.example.com

But I can't edit test.example.com

$ mirrorbits edit test.example.com
secondtest.example.com
test.example.com

I proceed to remove secondtest.example.com so i can edit test.example.com

$ mirrorbits remove secondtest.example.com
Mirror removed successfully
$ mirrorbits edit test.example.com

I then find out I can't edit the displayname of this mirror.
I end up removing it completely and recreating it with the new displayname

When I tried this previously I also was not able to recreate the same mirrorname, it complains the mirror already exists:

$ mirrorbits add <lots of info> z.os6.org
Mirror z.os6.org already exists!
$ mirrorbits edit z.os6.org
No match for z.os6.org

crash in askRole

Trying to run this (current git checkout) on Ubuntu 14.04, with sentinel disabled, every command crashes as follows:

panic: runtime error: index out of range

goroutine 1 [running]:
main.(*redisobj).askRole(0xc208038c40, 0x7f10d8e8f5b8, 0xc20805d220, 0x0, 0x0, 0x0, 0x0)
        /home/mirrorbits/src/github.com/etix/mirrorbits/redis.go:184 +0x180
main.(*redisobj).connect(0xc208038c40, 0x0, 0x0, 0x0, 0x0)
        /home/mirrorbits/src/github.com/etix/mirrorbits/redis.go:161 +0x360
main.(*cli).CmdAdd(0xcb4bd0, 0xc20800a020, 0x4, 0x4, 0x0, 0x0)
        /home/mirrorbits/src/github.com/etix/mirrorbits/commands.go:269 +0xc25

Commenting out the role, err := r.askRole(c) on line 161 (and the following ifs) makes it run without crashing.

Allow renaming a mirror

A mirror, once added cannot be renamed. We need a way to change that without causing too much trouble within a cluster.

non-refreshed files cause issue in mirrorlist

See http://mirrors.kodi.tv/test-builds/test.txt?mirrorlist

I've added a test file because we were debugging another issue (excessive disk reads by mirorrbits child processes) and wanted to take a look at the mirrorlist for this file.
Obviously because the file is not yet refreshed from local disk, this doesn't work but should probably be handled better.

template: mirrorlist.html:78:89: executing "body" at <$v.FileInfo.Path>: nil pointer evaluating *main.FileInfo.Path

Has to do with last changed made in #9

Multiple IP adresses: no ASN so no proper balancing

When connecting from mobile devices mirrorbits 'sees' two external IP's for the device, and is unable to select an ASN. The result is that the client does not receive a download at optimal speed.

For example: http://up.kibje.com/20150803/Screenshot_2015-08-03-17-27-09.png
I have IP's 212.67.184.99 (ASN8608) and 66.249.81.223 (ASN15169)

For mobile the first address almost always corresponds to the location-defining IP of the client. In my case when I am on WLAN I get the proxy of my location, when I am not on WLAN I get the proxy address of my mobile phone provider.
The second IP address is caused by mobile browser optimization services (eg Google / Akamai / Apple) which most phone manufacturers are using on their OS's these days. They can also be caused by webpage filtering software but that is less common.

In my opinion the first address should always be selected if two or more addresses are available.

Support .sha1 / .sha256 / .md5 hashes on file extensions

If this option is ever merged it should be made optional.

The question is, what are we supposed to do if a .sha1 file already exists on the filesystem?

  • Treat it like any other file and redirect on a mirror?
  • Show the file on the filesystem (considering that it might be different)?
  • Show the one computed by mirrorbits?
  • Something else?

Feature: Keep track of sync time of external mirror

Easy feature:
- Make MirrorBits output a serverlist that is compatible with mirmon

Better feature:
Have something like "beaconFile" in config, which is a file that every server has with a timestamp in it. Save the content of beaconfile in the redis database and show the diff betweeen MirrorBits beaconFile and Mirrors beaconFile.

This way, ?mirrorlist can show a table as:

Mirrorname Sync status
Server 1 In sync
Server 3 In sync
Server 4 Out of sync by 10 hours and 14 seconds
Server 2 Out of sync by 2 days, 12 hours and 14 seconds

this happens everytime i go to the download url.

The ?mirrorlist works fine but the moment i try and grab a file i get this.

2015/05/08 20:25:17 http: panic serving 107.185.xx.xxx:22686: runtime error: index out of range
goroutine 40 [running]:
net/http.func·011()
/usr/lib/go/src/pkg/net/http/server.go:1100 +0xb7
runtime.panic(0x7e3260, 0xc6c81c)
/usr/lib/go/src/pkg/runtime/panic.c:248 +0x18d
main.(_RedirectRenderer).Write(0xc84fc0, 0xc208379980, 0xc20845a600, 0x8, 0x0, 0x0)
/home/etix/dev/go/src/github.com/etix/mirrorbits/pagerenderer.go:65 +0x588
main.(_HTTP).mirrorHandler(0xc20801a320, 0x7f41fe644978, 0xc20804cf00, 0xc2081225b0, 0xc208379980)
/home/etix/dev/go/src/github.com/etix/mirrorbits/http.go:251 +0x5e2
main.(_HTTP).requestDispatcher(0xc20801a320, 0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/home/etix/dev/go/src/github.com/etix/mirrorbits/http.go:157 +0x130
main._HTTP.(main.requestDispatcher)·fm(0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/home/etix/dev/go/src/github.com/etix/mirrorbits/http.go:71 +0x44
main.func·002(0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/home/etix/dev/go/src/github.com/etix/mirrorbits/gzip.go:33 +0x2ec
net/http.HandlerFunc.ServeHTTP(0xc208000eb0, 0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/usr/lib/go/src/pkg/net/http/server.go:1235 +0x40
net/http.(_ServeMux).ServeHTTP(0xc208026ba0, 0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/usr/lib/go/src/pkg/net/http/server.go:1511 +0x1a3
net/http.serverHandler.ServeHTTP(0xc2080d44e0, 0x7f41fe644978, 0xc20804cf00, 0xc2081225b0)
/usr/lib/go/src/pkg/net/http/server.go:1673 +0x19f
net/http.(_conn).serve(0xc208111680)
/usr/lib/go/src/pkg/net/http/server.go:1174 +0xa7e
created by net/http.(*Server).Serve
/usr/lib/go/src/pkg/net/http/server.go:1721 +0x313

monitor loop causing excessive disk read

The monitor loop

-monitor=true 

seems to be scanning all files on disk by reading the full file, then waiting 5 minutes and starting over again. We are seeing continuous 50-100 MB/sec disk read.

It seems (or so i am told by people smarter than me) that this could be implemented by using the linux inotify system for any loops after the first one. inotify is supported in go it seems.
That way mirrorbits would be notified of filesystem changes in the folder, and could selectively add files / hash them.

For now we have had to disable the monitor loop and manually set up crontabs. However this feels cludgy. :)

Allow individual mirror reporting

Client sites at present don't have a requirement to include a link to report a mirror issue. Similarly, one cannot provide "feedback" in the form of location correction, which might be fairly important.

I mention this because there are a number of mirrors for a particular client that are adversely narrow in bandwidth - I just started a download of VLC that would have taken half an hour to complete had I not located the files on another mirror.

Additionally, my development server is located in France. However, rather than a French provider, the provider selected is located in the British Midlands. Geographically, there are at least four better options.

mirrorlist: google maps API requires an API key

Google Maps returns "The Google Maps API server rejected your request. This service requires an API key.".

According to https://stackoverflow.com/questions/38462525/google-maps-static-api-is-asking-for-api-key, all new servers online after June 22nd 2016 require an API key.

I don't know if adding an API key is feasible or not, due to restrictions from google on number of requested maps per day, or if it would be better to look at implementing a different provider.

(I'm willing to do either in a PR)

Enforce HTTPS for distribution of software as a security measure against targeted malware attacks

Following Snowden NSA and Wikileaks CIA releases the internet community has been shaked in the understanding of how massive surveillance and targeted attacks works.

The basic attacks to infect computer with software malware is to intercept "on the wire" the package download, infect it "on-the-fly" and let the end-user finish the download and install it.

This major attack can be prevented by having a default HTTPS transport from the download mirror, considering that the additional costs of HTTPS vs HTTP is today negligible.

This ticket is to have mirrorbits to enforce all of the mirror download URLs to be only HTTPS, operating a plan to enforce HTTPS as the only download method, eventually working closely with the download mirrors.

Add JSON endpoint to list all mirrors

For our about page (https://media.ccc.de/about.html) we use JSON to render a table of all mirrors.
Previously we would list all active mirrors, their URLs and the number of files on the mirror.

I thought about writing a separate go program later this month to get the information from the redis database, but maybe it would make sense to include this in mirrorbits?

Feature: Support MD5 hashes

Is it possible to add the md5 hash of a file and return it via json as well as the sha1?

Long term it would be nice if you could add the ability to append .sha1 or .md5 to a given filename and have it download the hash in a similar way to how mirrorbrain works.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.