diff --git a/conf/app.ini b/conf/app.ini
index f49bdfecab..3ca64d3aa6 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -190,6 +190,13 @@ ENABLE_REVERSE_PROXY_AUTHENTICATION = false
 ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
 ; Enable captcha validation for registration
 ENABLE_CAPTCHA = true
+; Default value for KeepEmailPrivate
+; New user will get the value of this setting copied into their profile
+DEFAULT_KEEP_EMAIL_PRIVATE = false
+; Default value for the domain part of the user's email address in the git log
+; if he has set KeepEmailPrivate true. The user's email replaced with a
+; concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
+NO_REPLY_ADDRESS = noreply.example.org
 
 [webhook]
 ; Hook task queue length, increase if webhook shooting starts hanging
diff --git a/models/user.go b/models/user.go
index 201d8c48fa..e6ba2fa6f3 100644
--- a/models/user.go
+++ b/models/user.go
@@ -75,19 +75,20 @@ type User struct {
 	Name      string `xorm:"UNIQUE NOT NULL"`
 	FullName  string
 	// Email is the primary email address (to be used for communication)
-	Email       string `xorm:"NOT NULL"`
-	Passwd      string `xorm:"NOT NULL"`
-	LoginType   LoginType
-	LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
-	LoginName   string
-	Type        UserType
-	OwnedOrgs   []*User       `xorm:"-"`
-	Orgs        []*User       `xorm:"-"`
-	Repos       []*Repository `xorm:"-"`
-	Location    string
-	Website     string
-	Rands       string `xorm:"VARCHAR(10)"`
-	Salt        string `xorm:"VARCHAR(10)"`
+	Email            string `xorm:"NOT NULL"`
+	KeepEmailPrivate bool
+	Passwd           string `xorm:"NOT NULL"`
+	LoginType        LoginType
+	LoginSource      int64 `xorm:"NOT NULL DEFAULT 0"`
+	LoginName        string
+	Type             UserType
+	OwnedOrgs        []*User       `xorm:"-"`
+	Orgs             []*User       `xorm:"-"`
+	Repos            []*Repository `xorm:"-"`
+	Location         string
+	Website          string
+	Rands            string `xorm:"VARCHAR(10)"`
+	Salt             string `xorm:"VARCHAR(10)"`
 
 	Created       time.Time `xorm:"-"`
 	CreatedUnix   int64     `xorm:"INDEX"`
@@ -170,13 +171,22 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
 	}
 }
 
+// getEmail returns an noreply email, if the user has set to keep his
+// email address private, otherwise the primary email address.
+func (u *User) getEmail() string {
+	if u.KeepEmailPrivate {
+		return fmt.Sprintf("%s@%s", u.LowerName, setting.Service.NoReplyAddress)
+	}
+	return u.Email
+}
+
 // APIFormat converts a User to api.User
 func (u *User) APIFormat() *api.User {
 	return &api.User{
 		ID:        u.ID,
 		UserName:  u.Name,
 		FullName:  u.FullName,
-		Email:     u.Email,
+		Email:     u.getEmail(),
 		AvatarURL: u.AvatarLink(),
 	}
 }
@@ -361,7 +371,7 @@ func (u *User) GetFollowing(page int) ([]*User, error) {
 func (u *User) NewGitSig() *git.Signature {
 	return &git.Signature{
 		Name:  u.DisplayName(),
-		Email: u.Email,
+		Email: u.getEmail(),
 		When:  time.Now(),
 	}
 }
@@ -616,6 +626,8 @@ func CreateUser(u *User) (err error) {
 		return ErrEmailAlreadyUsed{u.Email}
 	}
 
+	u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
+
 	u.LowerName = strings.ToLower(u.Name)
 	u.AvatarEmail = u.Email
 	u.Avatar = base.HashEmail(u.AvatarEmail)
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index f020f365d2..1fa5b55c67 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -38,12 +38,14 @@ type InstallForm struct {
 	RegisterConfirm bool
 	MailNotify      bool
 
-	OfflineMode           bool
-	DisableGravatar       bool
-	EnableFederatedAvatar bool
-	DisableRegistration   bool
-	EnableCaptcha         bool
-	RequireSignInView     bool
+	OfflineMode             bool
+	DisableGravatar         bool
+	EnableFederatedAvatar   bool
+	DisableRegistration     bool
+	EnableCaptcha           bool
+	RequireSignInView       bool
+	DefaultKeepEmailPrivate bool
+	NoReplyAddress          string
 
 	AdminName          string `binding:"OmitEmpty;AlphaDashDot;MaxSize(30)" locale:"install.admin_name"`
 	AdminPasswd        string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"`
@@ -97,11 +99,12 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding
 
 // UpdateProfileForm form for updating profile
 type UpdateProfileForm struct {
-	Name     string `binding:"OmitEmpty;MaxSize(35)"`
-	FullName string `binding:"MaxSize(100)"`
-	Email    string `binding:"Required;Email;MaxSize(254)"`
-	Website  string `binding:"Url;MaxSize(100)"`
-	Location string `binding:"MaxSize(50)"`
+	Name             string `binding:"OmitEmpty;MaxSize(35)"`
+	FullName         string `binding:"MaxSize(100)"`
+	Email            string `binding:"Required;Email;MaxSize(254)"`
+	KeepEmailPrivate bool
+	Website          string `binding:"Url;MaxSize(100)"`
+	Location         string `binding:"MaxSize(50)"`
 }
 
 // Validate valideates the fields
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 9a8a52e195..aedeb55285 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -838,6 +838,8 @@ var Service struct {
 	EnableReverseProxyAuth         bool
 	EnableReverseProxyAutoRegister bool
 	EnableCaptcha                  bool
+	DefaultKeepEmailPrivate        bool
+	NoReplyAddress                 string
 }
 
 func newService() {
@@ -850,6 +852,8 @@ func newService() {
 	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool()
+	Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
+	Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org")
 }
 
 var logLevels = map[string]string{
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index bcb9df8717..21bc1d5c77 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -124,6 +124,10 @@ save_config_failed = Fail to save configuration: %v
 invalid_admin_setting = Admin account setting is invalid: %v
 install_success = Welcome! We're glad that you chose Gitea, have fun and take care.
 invalid_log_root_path = Log root path is invalid: %v
+default_keep_email_private = Default Value for Keep Email Private
+default_keep_email_private_popup = This is the default value for the visibility of the user's email address. If set to true the email address of all new users will be hidden until the user changes his setting.
+no_reply_address = No-reply Address
+no_reply_address_helper = Domain for the user's email address in git logs if he keeps his email address private. E.g. user 'joe' and 'noreply.example.org' will be 'joe@noreply.example.org'
 
 [home]
 uname_holder = Username or email
@@ -307,6 +311,8 @@ add_new_email = Add new email address
 add_email = Add email
 add_email_confirmation_sent = A new confirmation email has been sent to '%s', please check your inbox within the next %d hours to complete the confirmation process.
 add_email_success = Your new email address was successfully added.
+keep_email_private = Keep Email Address Private
+keep_email_private_popup = Your email address will be hidden from other users if this option is set.
 
 manage_ssh_keys = Manage SSH Keys
 add_key = Add Key
@@ -1112,6 +1118,8 @@ config.disable_key_size_check = Disable Minimum Key Size Check
 config.enable_captcha = Enable Captcha
 config.active_code_lives = Active Code Lives
 config.reset_password_code_lives = Reset Password Code Lives
+config.default_keep_email_private = Default Value for Keep Email Private
+config.no_reply_address = No-reply Address
 
 config.webhook_config = Webhook Configuration
 config.queue_length = Queue Length
diff --git a/routers/install.go b/routers/install.go
index 113fd1592e..080b76d4be 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -111,6 +111,8 @@ func Install(ctx *context.Context) {
 	form.DisableRegistration = setting.Service.DisableRegistration
 	form.EnableCaptcha = setting.Service.EnableCaptcha
 	form.RequireSignInView = setting.Service.RequireSignInView
+	form.DefaultKeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
+	form.NoReplyAddress = setting.Service.NoReplyAddress
 
 	auth.AssignForm(form, ctx.Data)
 	ctx.HTML(200, tplInstall)
@@ -291,6 +293,8 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
 	cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration))
 	cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(form.EnableCaptcha))
 	cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView))
+	cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(com.ToStr(form.DefaultKeepEmailPrivate))
+	cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(com.ToStr(form.NoReplyAddress))
 
 	cfg.Section("").Key("RUN_MODE").SetValue("prod")
 
diff --git a/routers/user/setting.go b/routers/user/setting.go
index a465b0cd8c..bba0f1e876 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -91,6 +91,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) {
 
 	ctx.User.FullName = form.FullName
 	ctx.User.Email = form.Email
+	ctx.User.KeepEmailPrivate = form.KeepEmailPrivate
 	ctx.User.Website = form.Website
 	ctx.User.Location = form.Location
 	if err := models.UpdateUser(ctx.User); err != nil {
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 94a2a2fcc5..f0c349b1de 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -119,6 +119,10 @@
 						<dd><i class="fa fa{{if .Service.DisableMinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>*/}}
 						<dt>{{.i18n.Tr "admin.config.enable_captcha"}}</dt>
 						<dd><i class="fa fa{{if .Service.EnableCaptcha}}-check{{end}}-square-o"></i></dd>
+						<dt>{{.i18n.Tr "admin.config.default_keep_email_private"}}</dt>
+						<dd><i class="fa fa{{if .Service.DefaultKeepEmailPrivate}}-check{{end}}-square-o"></i></dd>
+						<dt>{{.i18n.Tr "admin.config.no_reply_address"}}</dt>
+						<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd>
 						<div class="ui divider"></div>
 						<dt>{{.i18n.Tr "admin.config.active_code_lives"}}</dt>
 						<dd>{{.Service.ActiveCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
diff --git a/templates/explore/users.tmpl b/templates/explore/users.tmpl
index 84ab7ad7fb..1fbe8653b3 100644
--- a/templates/explore/users.tmpl
+++ b/templates/explore/users.tmpl
@@ -16,7 +16,7 @@
 									{{if .Location}}
 										<i class="octicon octicon-location"></i> {{.Location}}
 									{{end}}
-									{{if and $.ShowUserEmail .Email $.IsSigned}}
+									{{if and $.ShowUserEmail .Email $.IsSigned (not .KeepEmailPrivate)}}
 										<i class="octicon octicon-mail"></i>
 										<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a>
 									{{end}}
diff --git a/templates/install.tmpl b/templates/install.tmpl
index 027d06166b..3489b72ebf 100644
--- a/templates/install.tmpl
+++ b/templates/install.tmpl
@@ -206,6 +206,17 @@
 									<input name="require_sign_in_view" type="checkbox" {{if .require_sign_in_view}}checked{{end}}>
 								</div>
 							</div>
+							<div class="inline field">
+								<div class="ui checkbox">
+									<label class="poping up" data-content="{{.i18n.Tr "install.default_keep_email_private_popup"}}"><strong>{{.i18n.Tr "install.default_keep_email_private"}}</strong></label>
+									<input name="default_keep_email_private" type="checkbox" {{if .default_keep_email_private}}checked{{end}}>
+								</div>
+							</div>
+							<div class="inline field">
+								<label for="no_reply_address">{{.i18n.Tr "install.no_reply_address"}}</label>
+								<input id="_no_reply_address" name="no_reply_address" value="{{.no_reply_address}}">
+								<span class="help">{{.i18n.Tr "install.no_reply_address_helper"}}</span>
+							</div>
 						</div>
 					</div>
 
diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl
index 37f94d2b79..198a9e3b60 100644
--- a/templates/user/profile.tmpl
+++ b/templates/user/profile.tmpl
@@ -22,7 +22,7 @@
 							{{if .Owner.Location}}
 								<li><i class="octicon octicon-location"></i> {{.Owner.Location}}</li>
 							{{end}}
-							{{if and $.ShowUserEmail .Owner.Email .IsSigned}}
+							{{if or (and $.ShowUserEmail .Owner.Email .IsSigned) (and .Owner.Email .IsSigned (not .Owner.KeepEmailPrivate))}}
 								<li>
 									<i class="octicon octicon-mail"></i>
 									<a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a>
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl
index a42d9c49c3..f01e6e9739 100644
--- a/templates/user/settings/profile.tmpl
+++ b/templates/user/settings/profile.tmpl
@@ -27,6 +27,12 @@
 							<label for="email">{{.i18n.Tr "email"}}</label>
 							<input id="email" name="email" value="{{.SignedUser.Email}}">
 						</div>
+						<div class="inline field">
+							<div class="ui checkbox" id="keep-email-private">
+								<label class="poping up" data-content="{{.i18n.Tr "settings.keep_email_private_popup"}}"><strong>{{.i18n.Tr "settings.keep_email_private"}}</strong></label>
+								<input name="keep_email_private" type="checkbox" {{if .SignedUser.KeepEmailPrivate}}checked{{end}}>
+							</div>
+						</div>
 						<div class="field {{if .Err_Website}}error{{end}}">
 							<label for="website">{{.i18n.Tr "settings.website"}}</label>
 							<input id="website" name="website" type="url" value="{{.SignedUser.Website}}">